When you extends Thread class, after that you can not extend any other class which you required. (As you know, Java does not allow inheriting more than one class).
When you implements Runnable, you can save a space for your class to extend any other class in future or now.
However, the significant difference is.
When you extends Thread class, each of your thread creates unique object and associate with it.
When you implements Runnable, it shares the same object to multiple threads.
When to use:
Whether to extend thread class or implement runnable interface ,the best OO practice is find out is the subclass is specialized class of thread or not ?
Extending the Thread class:
When your class is extending the Thread class then your class becomes a single thread which is inheriting all the properties and characteristics of the Thread class and it becomes heavy.
Implementing the Runnable interface:
When your class implements the Runnable interface then you only override the run() method, but you create one or more instance(s) of the Thread class in that instance you pass the instance of your Runnable interface implemented class and then you apply the start() method on the Thread instance. So this instance(s) creates a separate Thread(s) and every individual Thread runs separately but not as a single heavy Thread in your program.