使用Lock和Condition实现哲学家算法问题

来源:互联网 发布:怎么加入湖南网络作协 编辑:程序博客网 时间:2024/06/02 01:37

问题

问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。

这里写图片描述

代码

代码逻辑:
多少个哲学家,就有多少个筷子,判断哲学家左右两边的筷子是否正在使用,如果正在被使用,则将当前哲学家阻塞起来

哲学家:

public class philosopher extends Thread{    private String id;    private Chopsticks chopsticks;    public philosopher(String id, Chopsticks chopsticks){        this.id = id;        super.setName(id);        this.chopsticks = chopsticks;    }    public void eat(){        System.out.println("哲学家-" + id + " is eating");        try {            sleep(10000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void think(){        System.out.println("哲学家-" + id + " is thinking");        try {            sleep(10000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    @Override    public void run() {        //think();        chopsticks.take();        eat();        chopsticks.put();    }}

筷子类:

class Chopsticks {    private boolean[] used;    private int count;    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    public Chopsticks(int count) {        this.count = count;        used = new boolean[count];        for (int i = 0; i < used.length; i++) {            used[i] = false;        }    }    public void take() {        lock.lock();        try {            int i = Integer.parseInt(Thread.currentThread().getName());            //只要左边或右边的筷子被拿走了,就一直阻塞            while (used[i] || used[ (i+1)%count ]) {                condition.await();            }            System.out.println("take: " + i + ", " + (i+1)%count);            used[i] = true;            used[ (i+1)%count ] = true;        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void put() {        lock.lock();        try {            int i = Integer.parseInt(Thread.currentThread().getName());            used[i] = false;            used[ (i+1)%count ] = false;            //唤醒所有阻塞的哲学家            condition.signalAll();            System.out.println("put: " + i + ", " + (i+1)%count);        } finally {            lock.unlock();        }    }}

测试类:

class Test{    public static void main(String[] args) {        Chopsticks chopsticks = new Chopsticks(5);        for (int i = 0; i < 5; i++) {            new philosopher(i+"", chopsticks).start();        }    }}

结果:

take: 0, 1take: 2, 3哲学家-2 is eating哲学家-0 is eatingput: 0, 1put: 2, 3take: 1, 2哲学家-1 is eatingtake: 3, 4哲学家-3 is eatingput: 3, 4put: 1, 2take: 4, 0哲学家-4 is eatingput: 4, 0