Multithreading: Runnable vs Thread

What is multithreading? First of all let us understand what is thread? A thread is simply flow of control in a program/ process.

Now Let’s understand what is multithreading? Let’s take an example, there is a code which reads data from a file and uploads it to a database. Let’s say there are 10 such files and each file takes 1 hr to finish data upload. In a single threaded environment, it will simply translate to 10 hrs job as our code will read and upload files one by one.  Whereas when we move to multithreading, that is multiple threads are executing at the same time asynchronously, it will result in parallel processing of these files and the total time taken might be close to time taken by one file only.

Before getting into details lets understand how to implement multithreading in Java? There are 2 ways to achieve this.

//1. Extend Thread class
public class ThreadTest extends Thread{
 public void test()
 {
  System.out.println("Hello from Thread");
 }
 public void run()
 {
  test();
 }
}
 //2. Implement Runnable interface 
public class RunnableTest implements Runnable{
 public void test()
 {
  System.out.println("Hello from Runnable");
 }
@Override
 public void run() {
  test();
 }
}

//And somewhere in the main method 
public static void main(String s[])
{
 Thread t1=new ThreadTest();
 t1.start();
 Thread t2=new Thread(new RunnableTest());
 t2.start();
}

As you can see the important method while using threads is “run”. This method gets called automatically by JVM whenever a thread starts.

Note that we do not call the run method directly, as that will be like calling a normal method and will wait for control to come back to calling class. Whereas using start will make sure the control flow continues without waiting for method call return. To understand what I am referring here, lets change the main method slightly

for(int i=0;i<20;i++)
{
 Thread t1=new ThreadTest();
 t1.start();
 Thread t2=new Thread(new RunnableTest());
 t2.start();
}

We will something like (no order)

Hello from Thread
Hello from Runnable
Hello from Thread
Hello from Runnable
Hello from Runnable
Hello from Thread
Hello from Thread
Hello from Thread
Hello from Runnable
Hello from Runnable

Now let’s change it to run

for(int i=0;i<20;i++)
{
 Thread t1=new ThreadTest();
 t1.run();
 Thread t2=new Thread(new RunnableTest());
 t2.run();
}

Output

Hello from Thread
Hello from Runnable
Hello from Thread
Hello from Runnable
Hello from Thread
Hello from Runnable

So not actually using multithreading here.

Coming back to original example. Now you can see if we write the code for uploading the data from file to run method, and execute it in multithreaded fashion, we will be able to upload files simultaneously.

We have seen 2 ways to create threads in Java, one by extending thread class and other by implementing runnable. Which is better?

Usually we go for implementing runnable. When implementing runnable we can only override run method, and that is the only thing which we need in most of the cases. Whereas when we extent Thread, we can override other methods like start, sleep, stop etc, which is usually not required. Additionally, extending Thread has the obvious implementation that now our class cannot extend any other class (as Java allows only one class to be extended).