multithreading - "implements Runnable" vs "extends Thread" in Java

ID : 356

viewed : 135

Tags : javamultithreadingrunnableimplementsjava-threadsjava

Top 5 Answer for multithreading - "implements Runnable" vs "extends Thread" in Java

vote vote

92

Yes: implements Runnable is the preferred way to do it, IMO. You're not really specialising the thread's behaviour. You're just giving it something to run. That means composition is the philosophically "purer" way to go.

In practical terms, it means you can implement Runnable and extend from another class as well... and you can also implement Runnable via a lambda expression as of Java 8.

vote vote

90

tl;dr: implements Runnable is better. However, the caveat is important

In general, I would recommend using something like Runnable rather than Thread because it allows you to keep your work only loosely coupled with your choice of concurrency. For example, if you use a Runnable and decide later on that this doesn't in fact require it's own Thread, you can just call threadA.run().

Caveat: Around here, I strongly discourage the use of raw Threads. I much prefer the use of Callables and FutureTasks (From the javadoc: "A cancellable asynchronous computation"). The integration of timeouts, proper cancelling and the thread pooling of the modern concurrency support are all much more useful to me than piles of raw Threads.

Follow-up: there is a FutureTask constructor that allows you to use Runnables (if that's what you are most comfortable with) and still get the benefit of the modern concurrency tools. To quote the javadoc:

If you don't need a particular result, consider using constructions of the form:

Future<?> f = new FutureTask<Object>(runnable, null) 

So, if we replace their runnable with your threadA, we get the following:

new FutureTask<Object>(threadA, null) 

Another option that allows you to stay closer to Runnables is a ThreadPoolExecutor. You can use the execute method to pass in a Runnable to execute "the given task sometime in the future."

If you'd like to try using a thread pool, the code fragment above would become something like the following (using the Executors.newCachedThreadPool() factory method):

ExecutorService es = Executors.newCachedThreadPool(); es.execute(new ThreadA()); 
vote vote

74

Moral of the story:

Inherit only if you want to override some behavior.

Or rather it should be read as:

Inherit less, interface more.

vote vote

61

Well so many good Answers, I want to add more on this. This will help to understand Extending v/s Implementing Thread.
Extends binds two class files very closely and can cause some pretty hard to deal with code.

Both approaches do the same job but there have been some differences.
The most common difference is

  1. When you extend Thread class, after that you can’t extend any other class which you required. (As you know, Java does not allow inheriting more than one class).
  2. When you implement Runnable, you can save space for your class to extend any other class in the future or now.

However, one significant difference between implementing Runnable and extending Thread is that
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.

The following example will help you to understand more clearly

//Implement Runnable Interface... class ImplementsRunnable implements Runnable {      private int counter = 0;      public void run() {         counter++;         System.out.println("ImplementsRunnable : Counter : " + counter);     } }  //Extend Thread class... class ExtendsThread extends Thread {      private int counter = 0;      public void run() {         counter++;         System.out.println("ExtendsThread : Counter : " + counter);     } }      //Use the above classes here in main to understand the differences more clearly... public class ThreadVsRunnable {      public static void main(String args[]) throws Exception {         // Multiple threads share the same object.         ImplementsRunnable rc = new ImplementsRunnable();         Thread t1 = new Thread(rc);         t1.start();         Thread.sleep(1000); // Waiting for 1 second before starting next thread         Thread t2 = new Thread(rc);         t2.start();         Thread.sleep(1000); // Waiting for 1 second before starting next thread         Thread t3 = new Thread(rc);         t3.start();          // Creating new instance for every thread access.         ExtendsThread tc1 = new ExtendsThread();         tc1.start();         Thread.sleep(1000); // Waiting for 1 second before starting next thread         ExtendsThread tc2 = new ExtendsThread();         tc2.start();         Thread.sleep(1000); // Waiting for 1 second before starting next thread         ExtendsThread tc3 = new ExtendsThread();         tc3.start();     } } 

Output of the above program.

ImplementsRunnable : Counter : 1 ImplementsRunnable : Counter : 2 ImplementsRunnable : Counter : 3 ExtendsThread : Counter : 1 ExtendsThread : Counter : 1 ExtendsThread : Counter : 1 

In the Runnable interface approach, only one instance of a class is being created and it has been shared by different threads. So the value of counter is incremented for each and every thread access.

Whereas, Thread class approach, you must have to create separate instance for every thread access. Hence different memory is allocated for every class instances and each has separate counter, the value remains same, which means no increment will happen because none of the object reference is same.

When to use Runnable?
Use Runnable interface when you want to access the same resources from the group of threads. Avoid using Thread class here, because multiple objects creation consumes more memory and it becomes a big performance overhead.

A class that implements Runnable is not a thread and just a class. For a Runnable to become a Thread, You need to create an instance of Thread and passing itself in as the target.

In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

When there is a need to extend a superclass, implementing the Runnable interface is more appropriate than using the Thread class. Because we can extend another class while implementing Runnable interface to make a thread.

I hope this will help!

vote vote

57

One thing that I'm surprised hasn't been mentioned yet is that implementing Runnable makes your class more flexible.

If you extend thread then the action you're doing is always going to be in a thread. However, if you implement Runnable it doesn't have to be. You can run it in a thread, or pass it to some kind of executor service, or just pass it around as a task within a single threaded application (maybe to be run at a later time, but within the same thread). The options are a lot more open if you just use Runnable than if you bind yourself to Thread.

Top 3 video Explaining multithreading - "implements Runnable" vs "extends Thread" in Java

Related QUESTION?