2017  Kodetalk | Feedback | Privacy Policy | Terms | About
userimage

inter thread communication in java with example

Inter Thread communication (wait(),notify(), notifyAll()):


1)    Two Threads can communicate with each other by using wait(), notify() and notifyAll() methods.
2)    The Thread which is excepting updation it has to call wait() method and the Thread which is performing updation it has to call notify() method. After getting notification the waiting Thread will get those updations.


Diagram:



3)
    wait(), notify() and notifyAll() methods are available in Object class but not in Thread class because Thread can call these methods on any common object.
4)    To call wait(), notify() and notifyAll() methods compulsory the current Thread should be owner of that object that is current Thread should has lock of that object that is current Thread should be in synchronized area. Hence we can call wait(), notify() and notifyAll() methods only from synchronized area otherwise we will get runtime exception saying IllegalMonitorStateException.
5)    Once a Thread calls wait() method on the given object 1st  it releases the lock of that object immediately and entered into waiting state.
6)    Once a Thread calls notify() (or) notifyAll() methods it releases the lock of that object but may not immediately.
7)    Except these (wait(),notify(),notifyAll()) methods there is no other place(method) where the lock release will be happen.

Method

Is Thread Releases Lock?

yield()

No

join()

No

sleep()

No

wait()

Yes

notify()

Yes

notifyAll()

Yes


8)    Once a Thread calls wait(), notify(), notifyAll() methods on any object then it releases the lock of that particular object but not all locks it has.
       1)    public final void wait()throws InterruptedException
       2)    public final native void wait(long ms)throws InterruptedException
       3)    public final void wait(long ms,int ns)throws InterruptedException
       4)    public final native void notify()
       5)    public final void notifyAll()
Diagram:


Example 1:

public class ThreadA
{
	public static void main(String[] args)throws InterruptedException
	{
		ThreadB b=new ThreadB();
		b.start();
		synchronized(b)
		{
			System.out.println("main Thread calling wait() method");//step-1
			b.wait();
			System.out.println("main Thread got notification call");//step-4
			System.out.println(b.total);
		}
	}
}
public class ThreadB extends Thread
{
	int total=0;
	public void run()
	{
		synchronized(this)
		{
			System.out.println("child thread starts calcuation");//step-2
			for(int i=0;i<=100;i++)
			{
				total=total+i;
			}
			System.out.println("child thread giving notification call");//step-3
			this.notify();
		}
	}
}

Output:

main Thread calling wait() method
child thread starts calculation
child thread giving notification call
main Thread got notification call
5050


Example 2:

Producer consumer problem:

Producer(producer Thread) will produce the items to the queue and consumer(consumer thread) will consume the items from the queue. If the queue is empty then consumer has to call wait() method on the queue object then it will entered into waiting state.
After producing the items producer Thread call notify() method on the queue to give notification so that consumer Thread will get that notification and consume items.


Diagram:


Example:



Notify vs notifyAll():

We can use notify() method to give notification for only one Thread. If multiple Threads are waiting then only one Thread will get the chance and remaining Threads has to wait for further notification. But which Thread will be notify(inform) we can’t expect exactly it depends on JVM.
We can use notifyAll() method to give the notification for all waiting Threads. All waiting Threads will be notified and will be executed one by one.
Note: On which object we are calling wait(), notify() and notifyAll() methods that corresponding object lock we have to get but not other object locks.


Example:

public class A
{
	public synchronized void foo(B b)
	{
		System.out.println("Thread1 starts execution of foo() method");
		try
		{
			Thread.sleep(2000);
		}
		catch (InterruptedException e)
		{}
		System.out.println("Thread1 trying to call b.last()");
		b.last();
	}
	public synchronized void last()
	{
		System.out.println("inside A, this is last()method");
	}
}
public class B
{
	public synchronized void bar(A a)
	{
	System.out.println("Thread2 starts execution of bar() method");
	try
	{
		Thread.sleep(2000);
	}
	catch (InterruptedException e)
	{}
	System.out.println("Thread2 trying to call a.last()");
	a.last();
	}
	public synchronized void last()
	{
	System.out.println("inside B, this is last() method");
	}
}
public class DeadLock implements Runnable
{
	A a=new A();
	B b=new B();
	DeadLock()
	{
		Thread t=new Thread(this);
		t.start();
		a.foo(b);//main thread
	}
	public void run()
	{
		b.bar(a);//child thread
	}
	public static void main(String[] args)
	{
		new DeadLock();//main thread
	}
}

Output:

Thread1 starts execution of foo() method
Thread2 starts execution of bar() method
Thread2 trying to call a.last()
Thread1 trying to call b.last()
//here cursor always waiting.


Daemon Threads:

The Threads which are executing in the background are called daemon Threads. The main objective of daemon Threads is to provide support for non daemon Threads.


Example:

Garbage collector


1)     We can check whether the Thread is daemon or not by using isDaemon() method.
                    public final boolean isDaemon();
2)    We can change daemon nature of a Thread by using setDaemon () method.
                    public final void setDaemon(boolean b);
3)    But we can change daemon nature before starting Thread only. That is after starting the Thread if we are trying to change the daemon nature we will get R.E saying IllegalThreadStateException.
4)     Main Thread is always non daemon and we can’t change its daemon nature because it’s already started at the beginning only.
5)     Main Thread is always non daemon and for the remaining Threads daemon nature will be inheriting from parent to child that is if the parent is daemon child is also daemon and if the parent is non daemon then child is also non daemon.
6)     Whenever the last non daemon Thread terminates automatically all daemon Threads will be terminated.


Example:

public class MyThread extends Thread
{
	public void run()
	{
		for(int i=0;i<10;i++)
		{
			System.out.println("lazy thread");
			try
			{
				Thread.sleep(2000);
			}
			catch (InterruptedException e)
			{}
		}
	}
}
public class DaemonThreadDemo
{
	public static void main(String[] args)
	{
	MyThread t=new MyThread();
	t.setDaemon(true);	           
	t.start();
	System.out.println("end of main Thread");
	}
}

Output:

End of main Thread
Lazy thread
1)     If we are commenting line 1 then both main and child Threads are non daemon and hence both will be executed until they completion.
2)     If we are not commenting line 1 then main Thread is non daemon and child Thread is daemon and hence whenever main Thread terminates automatically child Thread will be terminated.


Deadlock vs Starvation:

1)    A long waiting of a Thread which never ends is called deadlock.
2)    A long waiting of a Thread which ends at certain point is called starvation.
3)    A low priority Thread has to wait until completing all high priority Threads.
4)    This long waiting of Thread which ends at certain point is called starvation.


How to kill a Thread in the middle of the line?


1)    We can call stop() method to stop a Thread in the middle then it will be entered into dead state immediately.
           public final void stop();
2)    stop() method has been deprecated and hence not recommended to use.


suspend and resume methods:

1)      A Thread can suspend another Thread by using suspend() method then that Thread will be paused temporarily.
2)      A Thread can resume a suspended Thread by using resume() method then suspended Thread will continue its execution.
                       1)    public final void suspend();
                       2)    public final void resume();
3)      Both methods are deprecated and not recommended to use.


RACE condition:

Executing multiple Threads simultaneously and causing data inconsistency problems is nothing but Race condition we can resolve race condition by using synchronized keyword.


Life cycle of a Thread: