Java thread priority <br />The special type of error related to multitasking that needs to be avoided is deadlock. Deadlock occurs when two threads have a circular dependency on a pair of synchronous objects. For example, suppose one thread enters the pipeline of object X and another thread enters the pipeline of object Y. If X's thread tries to call Y's synchronization method, it will be locked as expected. The Y thread also wants to call some synchronization methods of X, and the thread waits forever, because in order to reach X, it must release its own lock of Y to make the first thread complete. Deadlock is a very difficult error to debug because:
Usually, it happens rarely, and it only happens when the time period of the two threads just matches.
It may contain more than two threads and synchronous objects (that is, deadlocks can occur when there are more complex sequences of events than the example just described).
To fully understand deadlock, it is useful to observe its behavior. The following example generates two classes, A and B, with foo( ) and bar( ) methods respectively. These two methods have a brief pause before calling methods of other classes. The main class, named Deadlock, creates instances of A and B, and then starts a second thread to set up a deadlock environment. The foo( ) and bar( ) methods use sleep( ) to force deadlock.
// An example of deadlock.class A { synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entere d A.foo"); try { Thread .sleep(1000); } catch(Exception e) { System.out.println("A Interrupted"); } System.out.println(name + "trying to call B.last()"); b.last( ); } synchronized void last() { System.out.println("Inside A.last"); }}class B { synchronized void bar(A a) { String name = Thread.currentThread( ).getName(); System .out.println(name + "entered B.bar"); try { Thread.sleep(1000); } catch(Exception e) { System.out.println("B Interrupted"); } System.out.printl n( name + "trying to call A.last()"); a.last(); } synchronized void last() { System.out.println("Inside A.last"); }}class Deadlock implements Runn able { A a = new A(); B b = new B(); Deadlock() { Thread.currentThread().setName("MainThread"); Thread t = new Thread(this, "RacingThread"); t.start(); a.foo(b); // get lock on a in this thread. System.out.println("Back in main thread"); } public void run() { b.bar(a); // get lock on b in other thread. System.out.println("Back in other thread"); } public static void main(String args[]) { new Deadlock(); }} After running the program, the output is as follows:
MainThread entered A.fooRacingThread entered B.barMainThread trying to call B.last()RacingThread trying to call A.last()
Because the program is deadlocked, you need to press CTRL-C to end the program. Press CTRL-BREAK on the PC (or press CTRL-/ under Solaris) and you can see the full thread and the pipeline buffer heap. You will see that RacingThread occupies the management process b while waiting for the management process a, and at the same time, MainThread occupies a waiting for the management process b. The program will never end. As this example illustrates, your multithreaded program is often locked, and deadlock is the first issue you should check.
Java thread deadlock <br />The special type of error related to multitasking that needs to be avoided is deadlock. Deadlock occurs when two threads have a circular dependency on a pair of synchronous objects. For example, suppose one thread enters the pipeline of object X and another thread enters the pipeline of object Y. If X's thread tries to call Y's synchronization method, it will be locked as expected. The Y thread also wants to call some synchronization methods of X, and the thread waits forever, because in order to reach X, it must release its own lock of Y to make the first thread complete. Deadlock is a very difficult error to debug because:
Usually, it happens rarely, and it only happens when the time period of the two threads just matches.
It may contain more than two threads and synchronous objects (that is, deadlocks can occur when there are more complex sequences of events than the example just described).
To fully understand deadlock, it is useful to observe its behavior. The following example generates two classes, A and B, with foo( ) and bar( ) methods respectively. These two methods have a brief pause before calling methods of other classes. The main class, named Deadlock, creates instances of A and B, and then starts a second thread to set up a deadlock environment. The foo( ) and bar( ) methods use sleep( ) to force deadlock.
// An example of deadlock.class A { synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entere d A.foo"); try { Thread .sleep(1000); } catch(Exception e) { System.out.println("A Interrupted"); } System.out.println(name + "trying to call B.last()"); b.last( ); } synchronized void last() { System.out.println("Inside A.last"); }}class B { synchronized void bar(A a) { String name = Thread.currentThread( ).getName(); System .out.println(name + "entered B.bar"); try { Thread.sleep(1000); } catch(Exception e) { System.out.println("B Interrupted"); } System.out.printl n( name + "trying to call A.last()"); a.last(); } synchronized void last() { System.out.println("Inside A.last"); }}class Deadlock implements Runn able { A a = new A(); B b = new B(); Deadlock() { Thread.currentThread().setName("MainThread"); Thread t = new Thread(this, "RacingThread"); t.start(); a.foo(b); // get lock on a in this thread. System.out.println("Back in main thread"); } public void run() { b.bar(a); // get lock on b in other thread. System.out.println("Back in other thread"); } public static void main(String args[]) { new Deadlock(); }} After running the program, the output is as follows:
MainThread entered A.fooRacingThread entered B.barMainThread trying to call B.last()RacingThread trying to call A.last()
Because the program is deadlocked, you need to press CTRL-C to end the program. Press CTRL-BREAK on the PC (or press CTRL-/ under Solaris) and you can see the full thread and the pipeline buffer heap. You will see that RacingThread occupies the management process b while waiting for the management process a, and at the same time, MainThread occupies a waiting for the management process b. The program will never end. As this example illustrates, your multithreaded program is often locked, and deadlock is the first issue you should check.