• 经典回顾:哲学家进餐问题(The Dinning Philosophers Problem)



    该问题涉及到五个哲学家,他们交替地进行思考和进餐。他们分别坐在位于一个圆形餐桌周围的五把椅子上,圆桌中央是一碗米饭,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。
    当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中。只有他同时拿到两根筷子时他才能开始进餐。完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。

    下面是哲学家进餐问题的Java实现的代码,涉及到线程:

      1/*
      2 * 创建日期 2006-4-5
      3 */

      4package threadDemo;
      5
      6class ChopStick {    //筷子类
      7    boolean available;
      8    ChopStick() {
      9        available=true;  //可以拿起
     10    }

     11    public synchronized void takeup() {  //拿起动作
     12        while(!available) {
     13            try {
     14                wait(); 
     15                System.out.println("哲学家等待另一根筷子");  
     16            }
     catch(InterruptedException e) { }
     17        }

     18        available=false;
     19    }

     20    
     21    public synchronized void putdown() {  //放下动作
     22        available=true;
     23        notify();
     24    }

     25}

     26
     27
     28class Philosopher extends Thread {   //哲学家类
     29    ChopStick left, right;  
     30    int philo_num;  //哲学家编号
     31    
     32    Philosopher (int num, ChopStick c1, ChopStick c2) {
     33        philo_num = num;
     34        left = c1;
     35        right = c2;
     36        setDaemon(true);  //此函数设true时,关闭主线程,子线程也跟着关闭
     37        //否则,关闭主线程,子线程继续执行
     38    }

     39    
     40    public void eat() {
     41        left.takeup();
     42        right.takeup();
     43        System.out.println("哲学家 " + (philo_num + 1+ " 正在进餐");
     44    }

     45    
     46    public void think() {
     47        left.putdown();
     48        right.putdown();
     49        System.out.println("哲学家 " + (philo_num + 1+ " 正在思考");
     50    }

     51    
     52    public void run() {
     53        while(true{
     54            eat();
     55            
     56            try {
     57                sleep(2000);  //吃的时间是2秒
     58            }

     59            catch (InterruptedException e) {}
     60
     61            think();
     62            
     63            try {
     64                sleep(2000);   //思考的时间也是2秒
     65            }

     66            catch (InterruptedException e) {}
     67        }

     68    }

     69}

     70
     71
     72public class Dining {      
     73    static ChopStick[] chopsticks = new ChopStick[5];  
     74    static Philosopher[] philos = new Philosopher[5];
     75    
     76    public static void main(String args[]) {
     77        for (int i = 0; i < 5; i ++ ) {
     78            chopsticks[i] = new ChopStick();
     79        }

     80        
     81        for (int i = 0; i < 5; i ++ ) {
     82            philos[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1% 5]);
     83        }

     84        
     85        for (int i = 0; i < 5; i ++{
     86            philos[i].start();
     87        }

     88        
     89        try
     90        {
     91            System.in.read(); //wait until Enter is pressed
     92            for (int i = 0; i < 5; i ++{
     93            
     94                philos[i].interrupt(); 
     95            }

     96        }

     97        catch(Exception e)
     98        { }
     99    }

    100}

    101
    102        
    103                


    运行结果:
    哲学家 1 正在进餐
    哲学家 3 正在进餐
    哲学家等待另一根筷子
    哲学家 3 正在思考
    哲学家等待另一根筷子
    哲学家 5 正在进餐
    哲学家等待另一根筷子
    哲学家 2 正在进餐
    哲学家 1 正在思考
    哲学家 5 正在思考
    哲学家 2 正在思考
    哲学家等待另一根筷子
    ...............
  • 相关阅读:
    如何手动同步 Chrome 浏览器的数据
    如何释放 Windows 10 系统的 C 盘空间
    Foxmail
    常用 Git 命令
    常用的 .gitignore 模板
    MySQL InnoDB Engine--数据页存储和INSERT操作
    MySQL InnoDB Engine--数据页存储和ALTER TABLE操作
    MySQL InnoDB Engine--数据页存储
    MySQL Index--BAK和MRR演示
    MySQL Execute Plan--Index Merge特性
  • 原文地址:https://www.cnblogs.com/bankey/p/367442.html
Copyright © 2020-2023  润新知