哲学家就餐问题

哲学家就餐问题在Java多线程中是一个死锁的典型案例;
问题描述:有一群哲学家,每个哲学家身边都有一支筷子(也就是说哲学家的人数和筷子的人数是相等的;)哲学家有两种状态:吃饭或者思考;我们现在就来具体实现一下:

import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Chopsticks{

    private boolean taken = false;

    public synchronized void take() throws InterruptedException{
        while(taken){
            wait();
            taken = true;
        }
    }

    public synchronized void drop(){
        taken = false;
        notifyAll();
    }
}

class Philosopher implements Runnable{

    private Chopsticks left;
    private Chopsticks right;
    private final int id;
    private final int ponderFactor;
    private Random rand = new Random(100);

    public void pause() throws InterruptedException{
        if(ponderFactor == 0)
            return;
        TimeUnit.SECONDS.sleep(rand.nextInt(3));
    }

    public Philosopher(Chopsticks left, Chopsticks right, int ident, int ponder){

        this.left = left;
        this.right = right;
        id = ident;
        ponderFactor = ponder;
    }

    public void grabbingChopstick() throws InterruptedException{
        //System.out.println(this + " " + "在抢右筷子");
        right.take();
        //System.out.println(this + " " + "在抢左筷子");
        left.take();
    }

    public void thinking() throws InterruptedException{
        System.out.println(this + " " + "在思考");
        pause();
    }

    public void eating() throws InterruptedException{
        System.out.println(this + " " + "在吃饭");
        pause();
        right.drop();
        left.drop();
    }

    @Override
    public void run() {

        try {
            while(!Thread.interrupted()){
                thinking();
                grabbingChopstick();
                eating();
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }

    public String toString(){
        return "哲学家-" + id;
    }
}


public class TestDemo {

    public static void main(String[] args) throws Exception {

        Scanner scan = new Scanner(System.in);
        int ponder = scan.nextInt();
        int size = ponder;  
        ExecutorService pool = Executors.newCachedThreadPool();
        Chopsticks[] sticks = new Chopsticks[size];

        for(int i = 0; i < size; i++){
            sticks[i] = new Chopsticks();
        }
        for(int j = 0; j < size; j++){
            if(j < size - 1){
                pool.execute(new Philosopher(sticks[j], 
                        sticks[(j + 1) % size], j + 1, ponder));
            }else{
                pool.execute(new Philosopher(sticks[0], sticks[j], j + 1, ponder));
            }
        }
    }
}

上述代码是优化了死锁问题的程序,但是如果我们把程序修改成一下这样,就很容易发生死锁(当出现每一个哲学家都拿到了一支筷子的时候,就会出现死锁现象):

for(int j = 0; j < size; j++){
    if(j < size){
        pool.execute(new Philosopher(sticks[j], 
                        sticks[(j + 1) % size], j + 1, ponder));
    }
}

哲学家问题就跟大家分享到这里,欢迎各位大佬批评指正!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值