Core Java - SPLessons

Java Threads

Chapter 32

SPLessons 5 Steps, 3 Clicks
5 Steps - 3 Clicks

Java Threads

Java Threads

shape Introduction

Java Threads, Doing some work or process is called Thread. More threads can run concurrently within a code, every thread in Java is created and managed by the java.lang.Thread class. To create a Java Threads developer has to follow some points as below explained.

shape Life Cycle
Of Thread

While starting any thread, thread can be any one of the state as follows. According to sun micro thread life cycle only follows 4 states, for the better understanding purpose Running state is also added.
New: When creating an object to the Thread class then thread will be in New state, but this process will be started before invoking start().
Runnable: The thread is in runnable state after invocation of start() method, but the thread scheduler has not selected it to be the running thread.
Running: Thread is in Running state if thread scheduler selected it.
Non-Runnable(Blocked):Here some methods will be performed like sleep().
Terminated: Thread goes to dead state after the completion of task.

shape Description

The thread is an execution instance, which gets separate CPU and memory allocation to execution its task.

Thread scheduler is responsible to allocate CPU time and memory for the registered threads the allocation depends upon the JVM implementation and thread priority.
Garbage Collector thread is responsible for cleaning unused objects
Thread main calls the main method of the Java class to start the execution Both G C thread and thread main are registered with the thread scheduler.

Creating Thread

shape Description

  • The task which should be done by thread must be implemented in the run() method.
  • A thread can be started by invoking the start() method in the thread object.
  • Whenever a start() method is invoked it registers thread to the thread scheduler and calls or invokes the run() method of the object.
  • If run() method is directly invoked the thread will not get separate CPU and memory,since it will not be registered with thread scheduler.
  • One can override the start() method in thread class but we loose the implementation of registering thread to the thread scheduler.

shape Example

The following is an example to create a thread.

package com.spl.thread;
public class Thread1 {
	public static void main(String[] args) {
		System.out.println("Program starts");
		ThreadDemo t=new ThreadDemo();
		Thread newT=new Thread(t);
		newT.start();
		System.out.println("Program ends");
		
	}
}
class ThreadDemo implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("Running A thread");
		for(int j=101;j<=110;j++)
		{
			System.out.println("j value="+j);
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
			e.printStackTrace();	
			}
			//1000ms delay
		}
	}
}

The following are the some reasons developers will prefer implement runnable.

  • Other APIs in Java accept work as Runnable and not specializations of the Thread class.
  • Java doesn’t support multiple inheritance, so if user class already extends an object, developer can’t also extend Thread.
    By implementing Runnable, multiple threads can share an instance of work. If user extended Thread, user would have have to create a new instance of work for each thread.

Output:

Program starts
Program ends
Running A thread
j value=101
j value=102
j value=103
j value=104
j value=105
j value=106
j value=107
j value=108
j value=109
j value=110

shape Example - 2

The following is an another example.

package com.spl.thread;

public class Thread2 {
	public static void main(String[] args) {
		System.out.println("Program starts");
                //parallel execution
		ThreadDemo1 d=new ThreadDemo1();
		d.start();
		ThreadDemo2 d1=new ThreadDemo2();
		d1.start();
		System.out.println("Program ends");
	}
}

class ThreadDemo1 extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("Running A thread");
		for(int j=101;j<=110;j++)
		{
			System.out.println("j value="+j);
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
			e.printStackTrace();	
			}
			//1000ms delay
		}
	}
}
class ThreadDemo2 extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("Running A thread");
		for(int j=101;j<=110;j++)
		{
			System.out.println("j value="+j);
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
			e.printStackTrace();	
			}
			//1000ms delay
		}
	}
}
  • A class implementing Runnable interface must override the run() method.That class or that object will not be called as thread object because its not having all the thread behaviors.That object is called as Runnable type object.
  • The Runnable type object cannot be run because in that object we do not have start() method.We can make the Runnable object a thread object by creating a thread object using Runnable object as an argument for the constructor.
  • Drawback of thread is Thread Synchronization and Thread Deadlock. If all the threads are accessing the same data at the same time deadlock will happen.

Output:

Program starts
Program ends
Running A thread
j value=101
Running A thread
j value=101
j value=102
j value=102
j value=103
j value=103
j value=104
j value=104
j value=105
j value=105
j value=106
j value=106
j value=107
j value=107
j value=108
j value=108
j value=109
j value=109
j value=110
j value=110

Thread Safe

shape Description

  • While developing multi-threaded application if a resource(method or data) is referred by more than one thread ,then data manipulation is done by thread might affect the other thread.To over come this we develop thread safe program ,which helps us to run a common resource by only one thread at a time.
  • Thread safe can be achieved by developing synchronized method.Both static and non-static methods can be synchronized.
  • If any thread enters synchronized non-static block,then that thread creates an Object Lock and utilizes the resource.This lock is known as Object Lock.
  • Until the current thread releases lock other thread can’t access.
  • Once an object lock is done the other threads cannot access any of the object members until it is released.
  • If a thread enters synchronized static block then Class Lock will be created,other threads cannot access any of the static members until the class lock is released.

shape Examples

The following is an example for the synchronization.

package com.spl.thread;
public class ThreadSafe {
	
	public static void main(String[] args) {
		System.out.println("Program starts");
		CommonResource cr1=new CommonResource();
		CommonResource cr2=new CommonResource();
		ThreadOne th1=new ThreadOne(cr1);
		ThreadTwo th2=new ThreadTwo(cr2);
		th1.setName("Thread One");
		th2.setName("Thread Two");
		th1.start();
		th2.start();
		System.out.println("Program ends");
		
	}
}
class CommonResource
{
	synchronized public void resource1()
	{
		System.out.println("Running resource1 by");
		System.out.println(Thread.currentThread().getName());
		for(int i=1;i<=5;i++)
		{
			System.out.println("i="+i);
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
	synchronized public void resource2()
	{
		System.out.println("Running resource2 by");;
		System.out.println(Thread.currentThread().getName());
		for(int j=101;j<=105;j++)
		{
			System.out.println("j="+j);
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
}
class ThreadOne extends Thread
{
	CommonResource cr1;
	ThreadOne(CommonResource cr1)
	{
		this.cr1=cr1;
	}
	public void run()
	{
		cr1.resource1();
	}
	
}
class ThreadTwo extends Thread
{
	CommonResource cr1;
	ThreadTwo(CommonResource cr1)
	{
		this.cr1=cr1;
	}
	public void run()
	{
		cr1.resource1();
	}
	
}

Output:

Program starts
Program ends
Running resource1 by
Thread Two
i=1
Running resource1 by
Thread One
i=1
i=2
i=2
i=3
i=3
i=4
i=4
i=5
i=5

Difference Between Serializable in thread and Synchronized

  • Synchronization refers to multi-threading. A synchronized block of code can only be executed by one thread at a time.
  • Serialization is a process of changing the present state of an object in the form of byte streams. After doing Java Serialization process one can read an object from the file, deserialization is used to recreate the exist state of an object.
  • Serialization is a strategy in Java for flattening objects out to disk or a stream and then reassembling them on the other end or when they are re-instantiated.
  • Thread safe can be achieved by developing synchronized method.Both static and non-static methods can be synchronized.

Inter Thread Communication

shape Description

  • An Inter thread communication can be achieved by wait() and notify() methods.
  • If a thread enters synchronized block and to complete its task if it is depending on other functionality of the object then the thread must be enter to waits statement by releasing the block.
  • Another thread should notify the threads in the wait state to resume back its work.This notification can be done by notify() method as well as notifyAll() method.
  • The notify() methods notifies only one thread at a time, where as notifyAll() methods notifies all the threads which all are in the wait state.
  • The wait(), notify() and notifyAll() methods must be used only inside synchronized block.
  • Inter thread communication is usefull to avoid deadlock condition.
  • If user use sleep() method instead of wait() then the thread takes the lock & enters into sleep state.notify() method will not have impact on the threads which is in sleep state.

Summary

shape Key Points

  • The Thread.sleep() is used to sleep a thread for an interval of time.
  • The Daemon thread in java is a service provider thread.