19、多執行緒的死鎖
阿新 • • 發佈:2018-12-22
在多執行緒系列文章第一篇中我們講解到了死鎖的概念。
由上圖可知,死鎖就是多個執行緒都在等待對方釋放自己所需要的鎖。 我們知道機器不像我們人這麼的謙讓,他們都是搶佔資源跑任務的。所以“你若不釋放,我打死也不會釋放。”
下面的例子演示了死鎖。
package com.demo3; public class MyObject implements Runnable { private Object lock = new Object(); private Object lock2 = new Object(); private Object lock3 = new Object(); @Override public void run() { if (Thread.currentThread().getName().equals("A")) { synchronized (lock) { try { System.out.println("執行緒A拿到lock"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock2) { System.out.println("執行緒A拿到lock2"); } } } if (Thread.currentThread().getName().equals("B")) { synchronized (lock2) { try { System.out.println("執行緒B拿到lock2"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock3) { System.out.println("執行緒B拿到lock3"); } } } if (Thread.currentThread().getName().equals("C")) { synchronized (lock3) { try { System.out.println("執行緒C拿到lock3"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock) { System.out.println("執行緒C拿到lock"); } } } } }
package com.demo3; public class Run { public static void main(String[] args) { MyObject myObject = new MyObject(); Thread threadA = new Thread(myObject,"A"); Thread threadB = new Thread(myObject,"B"); Thread threadC = new Thread(myObject,"C"); threadA.start(); threadB.start(); threadC.start(); } }
執行結果:
執行緒A拿到lock
執行緒B拿到lock2
執行緒C拿到lock3
abc,執行緒拿到 lock lock2 lock3之後,就再也沒有釋放鎖,來達到交、交換鎖,執行後續程式碼的情況。這也就是死鎖。為了進一步驗證我們的判斷,我們使用terminal命令列來檢視:
F:\daydayup\thread-demo>jps 11952 Launcher 1348 Run 8740 7084 Jps F:\daydayup\thread-demo>jstack -l 1348 2018-12-22 15:19:55 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode): ...... Java stack information for the threads listed above: =================================================== "C": at com.demo3.MyObject.run(MyObject.java:46) - waiting to lock <0x00000000d732d6c0> (a java.lang.Object) - locked <0x00000000d732d6e0> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) "A": at com.demo3.MyObject.run(MyObject.java:20) - waiting to lock <0x00000000d732d6d0> (a java.lang.Object) - locked <0x00000000d732d6c0> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) "B": at com.demo3.MyObject.run(MyObject.java:33) - waiting to lock <0x00000000d732d6e0> (a java.lang.Object) - locked <0x00000000d732d6d0> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) Found 1 deadlock.
有輸出結果足以驗證死鎖的產生。我們在日常工作中,應該避免死鎖。