Extends Thread Vs Implements Runnable
Java only allows single inheritance , which means that if you inherit from Thread you won't be able to inherit from any other class. Implementing the Runnable interface doesn't have this limitation, since your class is allowed to implement any number of interfaces.
If you extend Thread class, all methods of Thread class will be inheriting to your class which you may not need. This will cause additional overhead. You can remove this overhead by implementing Runnable interface .
In OOPs (object oriented programming), extending a class means modifying or improving the existing class . If you are not modifying the class, then it is not a good practice to extend it. So, implementing Runnable will be the best object oriented design practice.
By implementing Runnable , multiple threads can share an instance of your work. If you extended Thread, you'd have to create a new instance of your work for each thread.
Separating task as Runnable means we can reuse the task and also has freedom to execute it from different means, since you cannot restart a Thread once it completes. So again "implements Runnable" vs. "extends Thread" for task, implementing Runnable will be the best choice.