Thread vs Runnable


Thread is a block of code which can execute concurrently with other threads in the JVM. You can create and run a thread in either ways; Extending Thread class, Implementing Runnable interface.

Both approaches do the same job but there have been some differences. Almost everyone have this question in their minds: which one is best to use? We will see the answer at the end of this post.

The most common difference is

  • When you extends 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).
  • 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.

The following example helps you to understand more clearly.

ThreadVsRunnable.java


class ImplementsRunnable implements Runnable {

 private int counter = 0;

 public void run() {
 counter++;
 System.out.println("ImplementsRunnable : Counter : " + counter);
 }
 }

 class ExtendsThread extends Thread {

 private int counter = 0;

 public void run() {
 counter++;
 System.out.println("ExtendsThread : Counter : " + counter);
 }
 }

 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 resource from the group of threads. Avoid using Thread class here, because multiple objects creation consumes more memory and it becomes a big performance overhead.

Apart from this, object oriented designs have some guidelines for better coding.

  • Coding to an interface rather than to implementation. This makes your software/application easier to extend. In other words, your code will work with all the interface’s subclasses, even ones that have not been created yet.
  • Interface inheritance (implements) is preferable – This makes your code is loosely coupling between classes/objects.(Note : Thread class internally implements the Runnable interface)

Example: coding to an interface.

Map subject = new HashMap();

Assigning HashMap object to interface Map,  suppose in future if you want to change HashMap to Hashtable or LinkedHashMap you can simple change in the declaration part is enough rather than to all the usage places. This point has been elaborately explained here.

Which one is best to use?

Ans : Very simple, based on your application requirements you will use this appropriately. But I would suggest, try to use interface inheritance i.e., implements Runnable.

Example : 

Map subject = new HashMap();

Assigning HashMap object to interface Map,  suppose in future if you want to change HashMap to Hashtable or LinkedHashMap you can simple change in the declaration area is enough rather than to all the usage places. I will explain this elaborately in the upcoming post.

 

About these ads

Tags: , , , , , , , , , , ,

7 Responses to “Thread vs Runnable”

  1. Jipeng Says:

    I agree with the decouple part. However, I am not sure if the share resource is a reason to use the runnable. As from your example, you are not sync your counter in the runnable which would lead to a race condition.

    I think another advantage of using the runnable is when many tasks involved. Executors can be used to save resource, that is, avoiding create threads for each tasks.

    Thanks,
    Jipeng

  2. Syed Gm Shah Says:

    nice work done i nderstand it very well thanks….!!!!

  3. vijay Says:

    If we pass the object to any method which is incrementing counter … it will do the same… where the thread doing sharing objects?????

    ImplementsRunnable rc = new ImplementsRunnable();

    you are passing same rc object to all thread so all the time it uses this object and modifies it… how come you are saying its because of implementing runnable only…. this kind of passing object can be done in Thread extending also right….

    Can you explain me with more significant difference … plz

  4. Jean Says:

    The only reason that it is sharing the same resource is because you are passing the same object to all the different Threads:

    ImplementsRunnable rc = new ImplementsRunnable();
    Thread t1 = new Thread(rc);

    Thread t2 = new Thread(rc);

    Thread t3 = new Thread(rc);

    Since Java is pass by value, it is passing the value (in this case the reference to rc) to each Thread. If you changed your implementation to the following, it would not access the same object:

    Thread t1 = new Thread(new ImplementsRunnable());

    Thread t2 = new Thread(new ImplementsRunnable());

    Thread t3 = new Thread(new ImplementsRunnable());

    You should now get the same result as extending Thread class.

  5. Sumit Kumar Says:

    This is very well explained and the code runs fine as well.
    However, I would also like to know the consequences that I might encounter when I call the Thread that implements Runnable,
    * from a different method of the same class.
    * from a method of a different class but same package.
    * from a method of a different class and different package.

    My initial testing suggests that, instantiation of a thread implementing Runnable interface from a different method makes it behave like instance of Thread class, i.e. the counter is not incremented for different Threads.

    Please correct me if I am wrong.
    Any light on this concept will really be appreciable.

    Thanks.

  6. pradip garala Says:

    nice…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 71 other followers

%d bloggers like this: