《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();
- }
- }
测试如图,在每个线程拿到右边的筷子之后,都进入死锁等待状态