解决哲学家就餐问题之奇数先拿右边筷子,再拿左边筷子,偶数则相反

1.标红的地方为算法的主要思想,理解了这问题就比较简单了;不懂的可以根据注释理解一下。

package test2;

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();
            eating();          
            chopsticsks.put(); 
        }
    }

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

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

class Chopsticsks {
    private boolean[] used = { false, false, false, false, false };    //初始化筷子为未使用

    public synchronized void take() {
        Philosopher p = (Philosopher) Thread.currentThread();
        int id = p.id;
        if(id%2==0) {

     //左边筷子不能拿直接等待,不要再去拿右边筷子
            while(used[id])
            {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("哲学家"+id+"拿起左边筷子"+id);
            used[id]=true;    
            while(used[(id+1)%5]) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
                System.out.println("哲学家"+id+"拿起右边筷子"+(id+1)%5);            
                used[(id+1)%5]=true;

        }
        else {

         //右边筷子不能拿直接等待,不要再去拿左边筷子
            while(used[(id+1)%5]) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            used[(id+1)%5]=true;
            System.out.println("哲学家"+id+"拿起右边筷子"+(id+1)%5);
            
            while(used[id]) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
                System.out.println("哲学家"+id+"拿起左边筷子"+id);
                used[id]=true;
        }

    }

    @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;
        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
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值