☰ Topics

Thread in Java

Thread is a small snippet of code and each thread defines a seperate path of execution.

Types of Thread:

  1. User Thread: User threads are threads which are created by the application or user. They are high priority threads. JVM will not exit until all user threads finish their execution. JVM wait for these threads to finish their task. These threads are foreground threads.

  2. Daemon Thread: Daemon threads are threads which are mostly created by the JVM. These threads always run in background. These threads are used to perform some background tasks like garbage collection and house keeping tasks. These threads are less priority threads. JVM will not wait for these threads to finish their execution. JVM will exit as soon as all user threads finish their execution. JVM doesn't wait for daemon threads to finish their task.
A mutithreaded program contains two or more parts that can run concurrently. It enables us to write very efficient programs that make maximum use of the CPU, because idle time can be kept to a minimum. In multithreading, multiple threads works at single instance of time. There is no scheduling in thread but it has life cycle. Thread class belongs to default package i.e. java.lang.

Life cycle of a thread:


 

The thread start its execution by the invokation of start() method which belong to Thread class. Then it comes to runnable state when run() method is invoked. run() is invoked implicitly as soon as start() is invoked. When start() is called, it start the execution of thread which begins from the run() method. After the successful termination of thread, it stops and exits.

When any interrupt occurs, again run() is invoked and the same process gets repeated. There can also be user interrupt. When suspend() method is invoked, the thread gets suspended and will remain in CPU till resume() method is invoked. Therefore, this step is deprecated i.e. not in use. By invoking resume(), again run() method is invoked and same process gets repeated. When sleep(time in ms) inside run(), the thread gets paused for certain period of time as specified in the argument of sleep() (in millisecond) and again it is resumed and thread comes to runnable state and same process gets repeated.

In case of multithreading, java includes an elegant interprocess communication mechanism via wait(), notify() and notifyAll() methods.

wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify() or notifyAll(). notify() wakes up the first thread that called wait() on the same object and notifyAll() wakes up all the threads that called wait() on the same object. The highest priority thread will run first. Again run() method is invoked and the same process gets repeated.

In multithreading, there is also a join() method which waits until the thread on which it is called terminates. Its name comes from the concept of the calling thread waiting until the specified thread joins it. It is inflexible while notify() and notifyAll() are more flexible than join(). So, it's better to use notify() and notifyAll().

There are two methods of creating a thread i.e. either by extending Thread class or implementing Runnable interface.

By extending Thread class
public class exthread1 extends Thread
{
	public void run()   //All the processing are done in run()
	{
		for(int i=0;i<=10;i++)
		{
			System.out.println(i);
			try          
			{
				Thread.sleep(1000);     //It will throw InterruptedException
			}
			catch(InterruptedException ex)
			{
				System.out.println(ex.toString());
			}
		}
	}
	public static void main(String[] arg)
	{
		exthread1 ob=new exthread1();
		System.out.println(ob.getName());     //To obtain thread's name
		ob.setName("T1");    //To change thread's name
		System.out.println(ob.getName());
		ob.start();    //start() is called and from here run() is automatically called
	}
}
                                

OUTPUT:

E:\java\new_java>java exthread1
Thread-0
T1
0
1
2
3
4
5
6
7
8
9
10
                        

By implementing Runnable interface
public class exthread2 implements Runnable
{
	public void run()   
	{
		for(int i=0;i<=10;i++)
		{
			System.out.println(i);
			try          
			{
				Thread.sleep(1000);     
			}
			catch(InterruptedException ex)
			{
				System.out.println(ex.toString());
			}
		}
	}
	public static void main(String[] arg)
	{
		exthread2 ob=new exthread2();
		Thread t=new Thread(ob);
		//ob.start();    //start() is not called using the object exthread2 class
		t.start();       //start() is called using the object of Thread class
	}
}
                            

OUTPUT:

E:\java\new_java>java exthread2
0
1
2
3
4
5
6
7
8
9
10
                        

Since, start() belongs to Thread class, not to Runnable interface, therefore, start() can't be called directly by using object of class. It is called by using the object of Thread class or object of exthread class must be referenced to Thread object.

Creating multithread

Given below is the static way of multithreading. Here, instance is created at compile time.
public class exth implements Runnable
{
	String tname="";
	Thread t;
	//To make it clear that which is the output of which thread, name should be attached to the thread
	public exth(String thname)     //To show the name of thread, constructor is used
	{
		tname=thname;          
		t=new Thread(this,tname);    //Second way to set the name
		t.setPriority(8);    //To set the priority of Thread, when the starts its priority is 5 i.e. the priority
		//Here, the priority of main thread is 5 but that of individual thread is 8
		t.start();
		System.out.println(tname+" is started");
	}
	public void run()   
	{
		for(int i=0;i<=10;i++)
		{
			System.out.println(tname+":"+i);
			try          
			{
				Thread.sleep(1000);     
			}
			catch(InterruptedException ex)
			{
				System.out.println(ex.toString());
			}
			System.out.println(tname+" is exiting");
		}
	}
	public static void main(String[] arg)
	{
		exth t1=new exth("one");
		exth t2=new exth("two");
		exth t3=new exth("three");
	}
}
                            

OUTPUT:

E:\java\new_java>java exth
one is started
one:0
two is started
two:0
three is started
three:0
three is exiting
two is exiting
one is exiting
two:1
three:1
one:1
three is exiting
two is exiting
two:2
one is exiting
three:2
one:2
two is exiting
two:3
three is exiting
three:3
one is exiting
one:3
two is exiting
two:4
three is exiting
three:4
one is exiting
one:4
two is exiting
two:5
three is exiting
three:5
one is exiting
one:5
two is exiting
two:6
three is exiting
one is exiting
three:6
one:6
two is exiting
two:7
three is exiting
three:7
one is exiting
one:7
two is exiting
two:8
three is exiting
three:8
one is exiting
one:8
two is exiting
two:9
three is exiting
one is exiting
three:9
one:9
two is exiting
two:10
three is exiting
one is exiting
one:10
three:10
two is exiting
one is exiting
three is exiting
                        

In multithreading, inter-thread communication should always be in Synchronized mode. Synchronization can be done through three methods i.e. wait() which is used with read and notify() and notifyAll() are used with write.

Program for interthread communication using synchronized method
class shared
{
	int data=0;
	synchronized void doWork()    //synchronized method for writing
	{
		try
		{
			Thread.sleep(1000);
			data++;
		}
		catch(Exception ex)
		{
			System.out.println(ex.toString());
		}
		notify();   //wakes up first thread that called wait()
	}
	synchronized int getResult()   //synchronized method for reading
	{
		try
		{
			wait();    //waits until other thread enters and called notify()
			System.out.println("Waiting...");
		}
		catch(Exception ex)
		{
			System.out.println(ex.toString());
		}
		return data;
	}
}

class th1 extends Thread
{
	shared sh;
	public th1(shared s1,String st)
	{
		super(st);    //Constructor of Thread class gets called
		sh=s1;
		start();      //run() gets called
	}
	public void run()
	{
		System.out.println("Result is "+sh.getResult());    //getResult() of shared class gets called
	}
	
}

class th2 extends Thread
{
	shared sh;
	public th2(shared s1,String st)
	{
		super(st);    //Constructor of Thread class gets called
		sh=s1;
		start();      //run() gets called
	}
	public void run()
	{
		sh.doWork();   //doWork() of shared class gets called
	}
	
}

class exrun
{
	public static void main(String[] arg)
	{
		shared sh=new shared();
		th1 t1=new th1(sh,"one");   //constructor of th1 class is called
		th2 t2=new th2(sh,"two");   //constructor of th2 class is called
	}
}
                            

OUTPUT:

E:\java\new_java>java exrun
Waiting...
Result is 1