解决哲学家就餐问题之最多允许四个哲学家同时进餐

1.标红的地方为算法的主要思想所在,理解了便十分简单了,不理解可以根据注释。

在这个算法中有个很巧妙的地方,便是用一个数组来表示哲学家是否在就餐。

package test3;

import java.util.concurrent.Semaphore;

class Philosopher extends Thread {
    
    int id;     
    private Chopsticsks chopsticsks; 
    public Philosopher(int num,Chopsticsks chopsticsks) {
        super();
        id=num;
        this.chopsticsks = chopsticsks;
    }

    public void run() {
        while (true) {
            thinking();        
            chopsticsks.take(id);
            System.out.println("哲学家"+id+"拿起左边筷子"+id);
            chopsticsks.take((id+1)%5);
            System.out.println("哲学家"+id+"拿起右边筷子"+(id+1)%5);
            eating();          
            chopsticsks.put(); 
        }
    }

    private void thinking() {
        System.out.println("哲学家 " + id + ": 开始思考!");
        try {
            sleep(3000);  
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void eating() {
        System.out.println("哲学家" + id+ " : 开始食用!");
        try {
            sleep(3000);   
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Chopsticsks {
    private boolean[] used = { false, false, false, false, false };    //初始化筷子为未使用
    private int[] num= {0,0,0,0,0};    //记录进餐的哲学家人数
    
    //统计除自己以外进餐的人数
    public synchronized int getNum(int id) {    
        int n=0;
        for(int i=0;i<5;++i) {
            if(num[i]==1 && i!=id) {  
                ++n;
            }
        }
        return n;
    }

    
    public synchronized void take(int chop) {
        Philosopher p = (Philosopher) Thread.currentThread();
        int id = p.id;
            while(getNum(id)>=4 || used[chop])
            {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }            
            used[chop]=true;
            num[id]=1;   //根据Id来赋值,避免了重复算拿两只筷子。

    }

    @SuppressWarnings("deprecation")
    public synchronized void put() {
        Philosopher p = (Philosopher) Thread.currentThread();
        int id = p.id;
        System.out.println("哲学家" + id + "放下手中的筷子:"+id+"、" +(id + 1) % 5);
        used[id] = false;          //将筷子设为为使用
        used[(id + 1) % 5] = false;
        num[id]=0;
        notifyAll();               //唤醒所有等待队列中的进程
    }
}

public class Test {
    public static void main(String[] args) {
        Chopsticsks chopsticsks = new Chopsticsks();

        new Philosopher(0,chopsticsks).start();
        new Philosopher(1,chopsticsks).start();
        new Philosopher(2,chopsticsks).start();
        new Philosopher(3,chopsticsks).start();
        new Philosopher(4,chopsticsks).start();
    }
}

2.结果截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值