Java 多執行緒實現死鎖場景
阿新 • • 發佈:2018-10-31
簡述:
《Java 程式設計思想》 P718 ~ P722
模擬死鎖的場景, 三個人 三根筷子,每個人需要拿到身邊的兩根筷子才能開始吃飯
出現死鎖的場景是,三個人都拿到了右邊的筷子,但是由於筷子都被搶佔,均無法獲得左邊的筷子
Chopstick.java
package com.anialy.test.multithread.philosophers; public class Chopstick { private boolean taken = false; public synchronized void take() throws InterruptedException{ while(taken) wait(); taken = true; } public synchronized void drop(){ taken = false; } }
Philosopher.java
package com.anialy.test.multithread.philosophers; import java.util.concurrent.TimeUnit; public class Philosopher implements Runnable { private Chopstick left; // 左邊的筷子 private Chopstick right; // 右邊的筷子 public Philosopher(Chopstick left, Chopstick right){ this.left = left; this.right = right; } private void pause() throws InterruptedException { TimeUnit.MILLISECONDS.sleep(100); } private void pauseToHoldChopstick() throws InterruptedException { TimeUnit.MILLISECONDS.sleep(1000); } public void run() { try { while(!Thread.interrupted()) { System.out.println(this + " thinking"); pause(); right.take(); System.out.println(this + " grabbing right"); // 當一個人拿起了一根筷子, 停頓一段時間,讓別人也搶到各自右邊的筷子 pauseToHoldChopstick(); left.take(); System.out.println(this + " grabbing left"); System.out.println(this + " eating"); pause(); // 完成之後放下筷子 right.drop(); System.out.println(this + " drop right"); left.drop(); System.out.println(this + " drop left"); } } catch (InterruptedException e){ System.out.println(this + " exiting via interrupt"); } } }
死鎖測試函式
DeadLockTest.java
package com.anialy.test.multithread.philosophers; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class DeadLockTest { public static void main(String[] args) throws InterruptedException, IOException { int size = 3; ExecutorService exec = Executors.newCachedThreadPool(); Chopstick[] sticks = new Chopstick[size]; for(int i=0; i<size; i++) sticks[i] = new Chopstick(); for(int i=0; i<size; i++) exec.execute(new Philosopher(sticks[i] , sticks[(i+1) % size])); TimeUnit.SECONDS.sleep(50); // 關掉所有的執行緒 exec.shutdownNow(); } }
測試如圖,在每個執行緒拿到右邊的筷子之後,都進入死鎖等待狀態