Java multi-thread deadlock
The following is an example of the deadlock.
Package com. qust. demo. money; class A {public synchronized void foo (B B) {System. out. println (Thread. currentThread (). getName () + "Enter foo of A"); try {Thread. sleep (200);} catch (InterruptedException ex) {ex. printStackTrace ();} System. out. println (Thread. currentThread (). getName () + "attempt to call the last of B"); B. last ();} public synchronized void last () {System. out. println ("A's last ()") ;}} class B {public synchronized void bar (A a) {System. out. println (Thread. currentThread (). getName () + "bar to B"); try {Thread. sleep (200);} catch (InterruptedException ex) {ex. printStackTrace ();} System. out. println (Thread. currentThread (). getName () + "attempt to call A's last");. last ();} public synchronized void last () {System. out. println ("B's last ()") ;}} public class DeadLock implements Runnable {A = new a (); B B = new B (); public void init () {Thread. currentThread (). setName ("main thread"); System. out. println ("Enter main thread");. foo (B);} public void run () {Thread. currentThread (). setName ("sub-thread"); System. out. println ("entering the sub-thread"); B. bar (a);} public static void main (String [] args) {DeadLock dl = new DeadLock (); new Thread (dl ). start (); dl. init ();}}
The running result is as follows:
The main thread enters the sub-thread. The main thread enters the foo sub-thread of A and the bar sub-thread of B tries to call the last main thread of A and tries to call the last main thread of B.
We can see that under normal circumstances, we should print "A's last ()" and "B's last ()" at last, but because of the thread deadlock, so the program has been waiting for execution and failed to run normally.
In the above Code, why is there a deadlock? Let's take a simple analysis.
First, although the start () of the sub-thread is before the init () of the main thread, it takes some time to enable the multi-thread. Therefore, we can see that it is the init () of the main thread () the method is executed first, and. foo (). The methods in Class A and Class B are both synchronous methods. Therefore, the objects of class A and B are synchronous locks. Before entering foo () of A, the thread will lock A and then sleep for 200 ms. At this time, the sub-thread calls bar () of B and will also lock B, then sleep for 200 ms. At this time, the main thread wakes up and tries to call the bar method of B. Because it is a synchronous method, it needs to lock B, but at this time B has been locked by the secondary thread, therefore, the main thread is always in the blocking status. When the sub-thread wakes up, it tries to call the synchronization method of A and also needs to apply A lock to a. However, at this time, the main thread holds the Lock of A and is in the blocking status, therefore, the sub-thread cannot be executed downward, and everyone is waiting for the other party to release the lock. Therefore, the deadlock we mentioned above occurs.
If we remove the synchronized of last () of A and B, the program does not need to lock the object before calling last (), so there will be no deadlock.
This is not the case at work, so we can only use this instance program to explain it.