
- Java併發教程
- 併發 - 首頁
- 併發 - 概述
- 併發 - 環境設定
- 併發 - 主要操作
- 執行緒間通訊
- 併發 - 同步
- 併發 - 死鎖
- 工具類示例
- 併發 - ThreadLocal
- 併發 - ThreadLocalRandom
- 鎖示例
- 併發 - 鎖
- 併發 - 讀寫鎖
- 併發 - 條件
- 原子變數示例
- 併發 - AtomicInteger
- 併發 - AtomicLong
- 併發 - AtomicBoolean
- 併發 - AtomicReference
- 併發 - AtomicIntegerArray
- 併發 - AtomicLongArray
- 併發 - AtomicReferenceArray
- 執行器示例
- 併發 - 執行器
- 併發 - ExecutorService
- ScheduledExecutorService
- 執行緒池示例
- 併發 - newFixedThreadPool
- 併發 - newCachedThreadPool
- newScheduledThreadPool
- newSingleThreadExecutor
- 併發 - ThreadPoolExecutor
- ScheduledThreadPoolExecutor
- 高階示例
- 併發 - Futures 和 Callables
- 併發 - Fork-Join 框架
- 併發集合
- 併發 - BlockingQueue
- 併發 - ConcurrentMap
- ConcurrentNavigableMap
- 併發實用資源
- 併發 - 快速指南
- 併發 - 實用資源
- 併發 - 討論
Java併發 - 死鎖
死鎖描述的是兩個或多個執行緒互相阻塞,永遠等待對方的情況。當多個執行緒需要相同的鎖,但是獲取鎖的順序不同時,就會發生死鎖。Java多執行緒程式可能會遭受死鎖,因為synchronized關鍵字會導致執行執行緒在等待與指定物件關聯的鎖(或監視器)時阻塞。以下是一個示例。
示例
public class TestThread { public static Object Lock1 = new Object(); public static Object Lock2 = new Object(); public static void main(String args[]) { ThreadDemo1 T1 = new ThreadDemo1(); ThreadDemo2 T2 = new ThreadDemo2(); T1.start(); T2.start(); } private static class ThreadDemo1 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 1: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 1: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 1: Holding lock 1 & 2..."); } } } } private static class ThreadDemo2 extends Thread { public void run() { synchronized (Lock2) { System.out.println("Thread 2: Holding lock 2..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 2: Waiting for lock 1..."); synchronized (Lock1) { System.out.println("Thread 2: Holding lock 1 & 2..."); } } } } }
編譯並執行上述程式時,你會發現死鎖的情況,程式輸出如下:
輸出
Thread 1: Holding lock 1... Thread 2: Holding lock 2... Thread 1: Waiting for lock 2... Thread 2: Waiting for lock 1...
上述程式將永遠掛起,因為任何執行緒都無法繼續執行,都在等待對方釋放鎖,你可以按 CTRL+C 結束程式。
死鎖解決方案示例
讓我們改變鎖的順序並執行相同的程式,看看兩個執行緒是否仍然互相等待:
示例
public class TestThread { public static Object Lock1 = new Object(); public static Object Lock2 = new Object(); public static void main(String args[]) { ThreadDemo1 T1 = new ThreadDemo1(); ThreadDemo2 T2 = new ThreadDemo2(); T1.start(); T2.start(); } private static class ThreadDemo1 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 1: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 1: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 1: Holding lock 1 & 2..."); } } } } private static class ThreadDemo2 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 2: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 2: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 2: Holding lock 1 & 2..."); } } } } }
僅僅改變鎖的順序就防止了程式進入死鎖狀態,並以以下結果完成:
輸出
Thread 1: Holding lock 1... Thread 1: Waiting for lock 2... Thread 1: Holding lock 1 & 2... Thread 2: Holding lock 1... Thread 2: Waiting for lock 2... Thread 2: Holding lock 1 & 2...
以上示例只是為了說明概念,然而,這是一個複雜的概念,在開發應用程式以處理死鎖情況之前,你應該深入研究它。
廣告