Joining
A thread invokes the join() method on another thread in order to wait for the other thread to complete its execution. Consider a thread t1 invokes the method join() on a thread t2. The join() call has no effect if thread t2 has already completed. If thread t2 is still alive, then thread t1 transits to the Blocked-for-join-completion state.
Below is a program showing how threads invoke the overloaded thread join method.
public class ThreadJoinDemo { public static void main(String[] args) { Thread t1 = new Thread("T1"); Thread t2 = new Thread("T2"); try { System.out.println("Wait for the child threads to finish."); t1.join(); if (!t1.isAlive()) System.out.println("Thread T1 is not alive."); t2.join(); if (!t2.isAlive()) System.out.println("Thread T2 is not alive."); } catch (InterruptedException e) { System.out.println("Main Thread interrupted."); } System.out.println("Exit from Main Thread."); } } |
Output
Wait for the child threads to finish.
Thread T1 is not alive.
Thread T2 is not alive.
Exit from Main Thread.
Thread T1 is not alive.
Thread T2 is not alive.
Exit from Main Thread.
Deadlock
There are situations when programs become deadlocked when each thread is waiting on a resource that cannot become available. The simplest form of deadlock is when two threads are each waiting on a resource that is locked by the other thread. Since each thread is waiting for the other thread to relinquish a lock, they both remain waiting forever in the Blocked-for-lock-acquisition state. The threads are said to be deadlocked.
Thread t1 at tries to synchronize first on string o1 and then on string o2. The thread t2 does the opposite. It synchronizes first on string o2 then on string o1. Hence a deadlock can occur as explained above.
Below is a program that illustrates deadlocks in multithreading applications
public class DeadLockExample { String o1 = "Lock "; String o2 = "Step "; Thread t1 = (new Thread("Printer1") { public void run() { while (true) { synchronized (o1) { synchronized (o2) { System.out.println(o1 + o2); } } } } }); Thread t2 = (new Thread("Printer2") { public void run() { while (true) { synchronized (o2) { synchronized (o1) { System.out.println(o2 + o1); } } } } }); public static void main(String[] args) { DeadLockExample dLock = new DeadLockExample(); dLock.t1.start(); dLock.t2.start(); } } |
Note: The following methods namely join, sleep and wait name the InterruptedException in its throws clause and can have a timeout argument as a parameter. The following methods namely wait, notify and notifyAllshould only be called by a thread that holds the lock of the instance on which the method is invoked. The Thread.start method causes a new thread to get ready to run at the discretion of the thread scheduler. The Runnable interface declares the run method. The Thread class implements the Runnable interface. Some implementations of the Thread.yield method will not yield to a thread of lower priority. A program will terminate only when all user threads stop running. A thread inherits its daemon status from the thread that created it
No comments:
Post a Comment