1. 程式人生 > >Java 多執行緒實現死鎖場景

Java 多執行緒實現死鎖場景

簡述:

《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();
	}
}


測試如圖,在每個執行緒拿到右邊的筷子之後,都進入死鎖等待狀態