Skip to main content

What is Multithreading? JAVA Multithreading Tutorial


It is almost end of 2017. The computer has evolved throughout its age from a simple, huge machine which was used for just simple numerical calculations to a small and swift electronic device which is affecting almost every aspect of our life. There are a lot of efforts involved in these enhancements in both hardware and software. Powerful hardware has been invented, and robust software techniques have been designed to improve hardware efficiency. One of these methods is multithreading and this is what we are going to talk about.
Multithreading is the ability of a single processing unit to execute multiple programs concurrently, apparently supported by the operating system. Multithreading is achieved either by multithreaded architecture or by software techniques or by both. All processors and OSs today support multi-thread execution.
We are talking about multithreading but what actually a thread is? A thread is a single unit a single processor can execute. The group consists of the shortest sequence of programmed instructions that are independently managed by operating system. Do not confuse thread with process and multithreading with multiprocessing. A running program, code to which processor is currently assigned is called a process while a thread may be the subpart of a process. A single process can have more than one threads. Multiple threads can share the same resources such as memory while processes do not share any resource with each other.

Advantages of multithreading:

Responsiveness: 

In a one-thread process, if the main execution thread blocks on a long-running task, the entire application can appear to freeze. By moving such long-running tasks to a worker thread that runs concurrently with the main execution thread, it is possible for the application to remain responsive to user input while executing tasks in the background. So multithreading can allow an application to remain responsive to user input.

Faster execution: 

Multithreading allows parallel execution and parallel execution leads to improved CPU performance.

Lower resource consumption:

 Different threads of the same process share same resources.

Better system utilization:

 In a single thread execution, resources can remain idle for some time. Multithreading technique does not allow any resource to be blocked and make use of it by a thread which requires the resource.

Simplified sharing and communication: 

Threads can communicate through data, code, and files they already shared. Unlike processes, threads do not require a message passing or shared memory mechanism to perform inter-process communications.

Parallelization: 

Applications running on multi-core or multi-CPU systems can use multithreading to divide the data and tasks into independent subtasks and let it run in parallel or concurrently.

The life cycle of a Thread:

A thread goes through different stages of its life cycle. It can be in one of the following states.
NEW – A thread that is just created and not yet started.
RUNNABLE – A thread in execution is in this state.
BLOCKED – a thread that is waiting to gain access to some resources is in BLOCKED state of the life-cycle.
WAITING – A thread is in WAITING state if it is waiting for another thread to complete execution.
TERMINATED – A thread that has completed its execution.

Java multithreading example: 

In Java, multithreading can be achieved in multiple ways. We are going to talk about 3 methods here.
1. By implementing Runnable interface.
2. By extending Thread class
3. By creating Thread object

1. By implementing Runnable interface:

MyThread.java
public class MyThread implements Runnable{

 int threadNum;
 int t;
 
 public MyThread(int threadNo) {
  this.threadNum = threadNo;
  t = 10;
 }
 public void run() {
  for (int  i = 0; i < 10; i++) {
   System.out.println("thread#" + threadNum + " : " + t);
   t = i;
  }
 } 
}
MainClass.java

public class MainClass {
 public static void main(String[] args) {
  ExecutorService application = Executors.newCachedThreadPool();
  application.execute(new MyThread(1));
  application.execute(new MyThread(2));
 }
}

2. By extending Thread class:

MyThread.java
public class MyThread extends Thread{
 int threadNum;
 public MyThread(int num) {
  threadNum = num;
 }
 
 public void run () {
  for (int i = 0; i < 10; i++)
  System.out.println(i + " at thread: " + threadNum);
 }
}
MainClass.java



public class MainClass {

 public static void main(String[] args) {
  MyThread t1 = new MyThread(1);
  MyThread t2 = new MyThread(2);
  
  t1.start();
  t2.start();
 }

}

3. By creating Thread object:


public class MainClass {

 public static void main(String[] args) {
  Thread t1 = new Thread(new Runnable() {

   public void run() {
    for (int i = 0; i < 10; i++)
     System.out.println("thread 1 running");
   }
   
  });
  Thread t2 = new Thread(new Runnable() {

   public void run() {
    for (int i = 0; i < 10; i++)
     System.out.println("thread 2 running");
   }
   
  });
  
  t1.start();
  t2.start();
 }
}
If you have any question, ask in the comments. I will try to respond ASAP.

Comments