Java Concurrency by Thread or Runable

Multithreading refers to two or more tasks executing concurrently within a single program. A thread is an independent path of execution within a program. Many threads can run concurrently within a program. Every thread in Java is created and controlled by the java.lang.Thread class. A Java program can have many threads, and these threads can run concurrently, either asynchronously or synchronously.

Multi-threading has several advantages over Multiprocessing:

  1. Threads are lightweight compared to processes
  2. Threads share the same address space and therefore can share both data and code
  3. Context switching between threads is usually less expensive than between processes
  4. Cost of thread intercommunication is relatively low that that of process intercommunication
  5. Threads allow different tasks to be performed concurrently.
public interfaceRunnable{
   void run();
}

One way to create a thread in java is to implement the Runnable Interface and then instantiate an object of the class. We need to override the run() method into our class which is the only method that needs to be implemented. The run() method contains the logic of the thread.
The procedure for creating threads based on the Runnable interface is as follows:
  1. A class implements the Runnable interface, providing the run() method that will be executed by the thread. An object of this class is a Runnable object.
  2. An object of Thread class is created by passing a Runnable object as argument to the Thread constructor. The Thread object now has a Runnable object that implements the run() method.
  3. The start() method is invoked on the Thread object created in the previous step. The start() method returns immediately after a thread has been spawned.
  4. The thread ends when the run() method ends, either by normal completion or by throwing an uncaught exception.
Below is a program that illustrates instantiation and running of threads using the runnable interface instead of extending the Thread class. To start the thread you need to invoke the start() method on your object.
class RunThread implements Runnable {

Thread runner;
public RunnableThread() {
}
public RunThread(String threadName) {
runner = new Thead(this, threadName);
System.out.println(runner.getName());
runner.start(); // (2) Start the thread.
}
public void run() {
System.out.println(Thread.currentThread());
}
}

public class RunExample {
public static void main(String[] args) {
Thread thread1 = new Thread(new RunnableThread(), "thread1");
Thread thread2 = new Thread(new RunnableThread(), "thread2");
RunThread thread3 = new RunThread("thread3");
thread1.start();
thread2.start();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread());
}
}

This approach of creating a thread by implementing the Runnable Interface must be used whenever the class being used to instantiate the thread object is required to extend some other class.

Threads by Extending Thread Class

The procedure for creating threads based on extending the Thread is as follows:
  1. A class extending the Thread class overrides the run() method from the Thread class to define the code executed by the thread.
  2. This subclass may call a Thread constructor explicitly in its constructors to initialize the thread, using the super() call.
  3. The start() method inherited from the Thread class is invoked on the object of the class to make the thread eligible for running.
Below is a program that illustrates instantiation and running of threads by extending the Thread class instead of implementing the Runnable interface. To start the thread you need to invoke the start() method on your object.
class ExtThread extends Thread {

ExtThread() {
}
ExtThread(String threadName) {
super(threadName); // Initialize thread.
System.out.println(this);
start();
}
public void run() {
System.out.println(Thread.currentThread().getName());
}
}

public class ExtThreadExample {

public static void main(String[] args) {
Thread thread1 = new Thread(new ExtThread(), "thread1");
Thread thread2 = new Thread(new ExtThread(), "thread2");
  Thread thread3 = new ExtThread();
Thread thread4 = new ExtThread();
Thread thread5 = new ExtThread("thread5");
  thread1.start();
thread2.start();
thread3.start();
thread4.start();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
}
//Display info about the main thread
System.out.println(Thread.currentThread());
}
}