See the Tutorial List

Introduction to Multithreading in Java

A program can be divided into a number of small processes. Each small process can be addressed as a single thread (a lightweight process). You can think of a lightweight process as a virtual CPU that executes code or system calls. You usually do not need to concern yourself with lightweight processes to program with threads. Multithreaded programs contain two or more threads that can run concurrently and each thread defines a separate path of execution. This means that a single program can perform two or more tasks simultaneously. For example, one thread is writing content on a file at the same time another thread is performing spelling check.

In Java, the word thread means two different things.

  • An instance of Thread class.
  • or, A thread of execution.

An instance of Thread class is just an object, like any other object in java. But a thread of execution means an individual "lightweight" process that has its own call stack. In java each thread has its own call stack.

thread call stack


The main thread

When we run any java program, the program begins to execute its code starting from the main method. Therefore, the JVM creates a thread to start executing the code present in main method. This thread is called as main thread. Although the main thread is automatically created, you can control it by obtaining a reference to it by calling currentThread() method.

Two important things to know about main thread are,

  • It is the thread from which other threads will be produced.
  • main thread must be always the last thread to finish execution.
class MainThread
{
 	public static void main(String[] args)
 	{
  		Thread t = Thread.currentThread();
  		t.setName("MainThread");
  		System.out.println("Name of thread is "+t);
 	}
}

Name of thread is Thread[MainThread,5,main]


Life cycle of a Thread

thread life cycle

  1. New : A thread begins its life cycle in the new state. It remains in this state until the start() method is called on it.
  2. Runnable : After invocation of start() method on new thread, the thread becomes runnable.
  3. Running : A thread is in running state if the thread scheduler has selected it.
  4. Waiting : A thread is in waiting state if it waits for another thread to perform a task. In this stage the thread is still alive.
  5. Terminated : A thread enter the terminated state when it complete its task.

Daemon Thread

In Java, Daemon threads are assigned a low priority. These threads run in the background to perform tasks such as garbage collection. Daemon thread does allow JVM from existing util all the threads finish their execution. When a JVM founds daemon threads it terminates the thread and then shutdown itself, it does not care Daemon thread whether it is running or not.

daemon-thread

Following are the methods in Daemon Thread

1. void setDaemon(boolean status)

In Java, this method is used to create the current thread as a daemon thread or user thread. If there is a user thread as obj1 then obj1.setDaemon(true) will make it a Daemon thread and if there is a Daemon thread obj2 then calling obj2.setDaemon(false) will make it a user thread.

Syntax:

	
public final void setDaemon(boolean on)
	

2. booleanisDaemon()

In Java, this method is used to check whether the current thread is a daemon or not. It returns true if the thread is Daemon otherwise it returns false.

Syntax:

	
public final booleanisDaemon()
	

Example:

	
public class DaemonDemo1 extends Thread 
{ 
    public DaemonDemo1(String name1)
    { 
        super(name1); 
    } 
    public void run() 
    {  
        if(Thread.currentThread().isDaemon()) 
        {  
System.out.println(getName() + " is Daemon thread");  
        }  
        else
        {  
System.out.println(getName() + " is User thread");  
        }  
    }  
    public static void main(String[] args) 
    {  
        DaemonDemo1 D1 = new DaemonDemo1("D1"); 
        DaemonDemo1 D2 = new DaemonDemo1("D2"); 
        DaemonDemo1 D3 = new DaemonDemo1("D3"); 

        D1.setDaemon(true);      
        D1.start();  
        D2.start(); 
        D3.setDaemon(true);  
        D3.start();         
    }  
}
	

deamon-thread-example


Thread Pool

In Java, is used for reusing the threads which were created previously for executing the current task. It also provides the solution if any problem occurs in the thread cycle or in resource thrashing. In Java Thread pool a group of threads are created, one thread is selected and assigned job and after completion of job, it is sent back in the group.

thread-pool

There are three methods of a Thread pool. They are as following:

1. newFixedThreadPool(int)

2. newCachedThreadPool()

3. newSingleThreadExecutor()

Following are the steps for creating a program of the thread pool

1. create a runnable object to execute.

2. using executors create an executor pool

3. Now Pass the object to the executor pool

4. At last shutdown the executor pool.

Example:

	
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class WorkerThread implements Runnable 
	{
		private String message;
		public WorkerThread(String a)
		{
			this.message=a;
		}
    public void run() 
	{
        System.out.println(Thread.currentThread().getName()+" (Start) message = "+message);
        processmessage();
        System.out.println(Thread.currentThread().getName()+" (End)");
    }
    private void processmessage() 
	{
        try 
		{  
			Thread.sleep(5000);  
		} 
		catch (InterruptedException e) 
		{
			System.out.println(e);
		}
    }
}
public class ThreadPoolDemo1 
{ 
    public static void main(String[] args) 
	{
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) 
		{
            Runnable obj = new WorkerThread("" + i);
            executor.execute(obj);
         }
        executor.shutdown();
        while (!executor.isTerminated()) 
		{
        }
        System.out.println("********All threads are Finished********");
    }
}
	

thread-pool-example


Thread Priorities

In Java, when we create a thread, always a priority is assigned to it. In a Multithreading environment, the processor assigns a priority to a thread scheduler. The priority is given by the JVM or by the programmer itself explicitly. The range of the priority is between 1 to 10 and there are three variables which are static to define priority in a Thread Class. They are as following:

1. public static int MIN_PRIORITY

It is the minimum priority that can be given to a thread. The value for this is 1.

2. public static int NORM_PRIORITY

It is the default priority that is given to a thread if it is not defined. The value for this is 0.

3. public static int MAX_PRIORITY

It is the maximum priority that can be given to a thread. The value for this is 10.

Get and Set methods in Thread priority

1. public final intgetPriority()

In Java, getPriority() method is in java.lang.Thread package. it is used to get the priority of a thread.

2. public final void setPriority(intnewPriority)

In Java setPriority(intnewPriority) method is in java.lang.Thread package. It is used to set the priority of a thread. The setPriority() method throws IllegalArgumentException if the value of new priority is above minimum and maximum limit.

Example:

	
import java.lang.*; 
class PriorityDemo1 extends Thread 
{ 
    public void run() 
    { 
System.out.println("Inside the run method"); 
    } 

    public static void main(String[]args) 
    { 
        PriorityDemo1 p1 = new PriorityDemo1(); 
        PriorityDemo1 p2 = new PriorityDemo1(); 
        PriorityDemo1 p3 = new PriorityDemo1(); 

System.out.println("P1 thread priority : " + p1.getPriority()); 
System.out.println("P2 thread priority : " + p2.getPriority());  
System.out.println("P3 thread priority : " + p3.getPriority()); 

        p1.setPriority(3); 
        p2.setPriority(6); 
        p3.setPriority(10); 

System.out.println("p1 thread priority : " + p1.getPriority()); 
System.out.println("p2 thread priority : " + p2.getPriority());  
System.out.println("p3 thread priority : " + p3.getPriority());
System.out.print(Thread.currentThread().getName()); 
System.out.println("Priority of Main Thread : "+ Thread.currentThread().getPriority()); 

Thread.currentThread().setPriority(10); 
System.out.println("Priority of Main Thread : "+ Thread.currentThread().getPriority()); 
    } 
}
	

thread-priority

Note: Thread priorities cannot guarantee that a higher priority thread will always be executed first than the lower priority thread. The selection of the threads for execution depends upon the thread scheduler which is platform dependent.