Multi Threading

Thread is a lightweight smallest unit of processing. Java uses threads by using a “Thread Class”.

Types of thread – 

  • User thread – The one that is created when an application begins.
  • Daemon thread – The ones that are used when we want to clean the application and are used in the background.

Multithreading is a process of executing two or more threads simultaneously to maximum utilization of CPU. Hence, it is also known as Concurrency in Java.

Advantages of Multithreading –

  • Multiple threads don’t allocate separate memory area, hence they save memory.
  • Context switching between threads takes less time.
  • Threads are independent, so operation on one thread won’t affect another. If an exception occurs in one thread, it doesn’t affect other threads.

Life cycle of a thread –

  • New –
    • In this phase, a new thread is created using class the “Thread class”.
    • It remains in this state until the program starts the thread.
    • It is also known as a born thread.
  • Runnable –
    •  In this phase, the instance of the thread is invoked with a start method.
    • The thread control goes to the scheduler to finish the execution.
    • It depends on the scheduler, whether to run the thread.
  • Running – 
    • When the thread starts executing, then the state is changed to a “running” state.
    • After that, the scheduler will select one thread from the thread pool, and it starts executing in the application.
  • Waiting –
    • In this state, a thread has to wait.
    • As multiple threads are running in the application, there is a need for synchronization between threads. Therefore, one thread has to wait, until the other thread gets executed.
  • Dead –
    • This is the state when the thread is terminated.
    • The thread is in a running state and as soon as it completed processing it is in “dead state”.

Mechanisms to create a thread –

  • Extending the Thread class –
    • Create a class that extends the Thread class.
    • Inside class override the run() method available in the Thread class. A thread begins its life inside a run() method.
    • Now create an object of this class and call the start() method to start the execution of a thread.
    • Start() invokes the run() method on the Thread object.
    • The class cannot extend any other class if we extend the Thread class because Java doesn’t support multiple inheritance.
    • Thread class provides some inbuilt methods like yield(), interrupt(), setPriority(), etc.
  • Implementing the Runnable Interface –
    • Create a new class that implements java.lang.Runnable interface.
    • This class overrides the run() method available in the interface.
    • After that, instantiate the Thread object and call the start() method on this object.
//Extending the Thread class

public class MultithreadingClass extends Thread {
	public void run(){
		try {
			//Fetching the thread that is running
			Thread.currentThread().getId();
		} catch(Exception e) {
			System.out.println("Exception caught");
		}
	}
}

public class Multithread {
	public static void main(String args[]) {
		int numberOfThreads = 10;
		for(int i=0; i<numberOfThreads; i++) {
			//calling start method
			MultithreadingClass mtClass = new MultithreadingClass();
			mtClass.start();
		}
	}
}
//Implementing the Runnable Interface

public class MultithreadingClass implements Runnable {
	public void run() {
		try {
			//Fetching the thread that is running
			Thread.currentThread().getId();
		} catch(Exception e) {
			System.out.println("Exception caught);
		}
	}
}

public class Multithread {
	public static void main(String args[]) {
		int numberOfThreads = 10;
		for(int i=0; i<numberOfThreads; i++) {
			//calling start method
			Thread mtClass = new Thread(new MultithreadingClass());
			mtClass.start();
		}
	}
}