哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题。

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

解决办法:

  • 拿筷子之前判断两支筷子是否有人使用,都无人使用时才能拿起筷子。
  • 不能独占一支筷子,造成死锁。
  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3.  
  4. public class Philosopher implements Runnable {
  5.  
  6. private static class Chopstick {
  7. private boolean[] chopsticks = {true, true, true, true, true};
  8.  
  9. public synchronized void take_two(int index) {
  10. while (!attempt(index)) {
  11. System.out.println(String.format("--哲学家%d--尝试拿筷子--失败...", index));
  12. try {
  13. wait();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. }
  18. System.out.println(String.format("--哲学家%d--尝试拿筷子--成功...", index));
  19. chopsticks[getLeft(index)] = false;
  20. chopsticks[getRight(index)] = false;
  21. }
  22.  
  23. private boolean attempt(int index) {
  24. System.out.println(String.format("--哲学家%d--尝试拿筷子...", index));
  25. return chopsticks[getLeft(index)] && chopsticks[getRight(index)];
  26. }
  27.  
  28. public synchronized void put_two(int index) {
  29. System.out.println(String.format("--哲学家%d--放下筷子...", index));
  30. chopsticks[getLeft(index)] = true;
  31. chopsticks[getRight(index)] = true;
  32. notifyAll();
  33. }
  34.  
  35. int getLeft(int index) {
  36. return (index - 1 + chopsticks.length) % chopsticks.length;
  37. }
  38.  
  39. int getRight(int index) {
  40. return index;
  41. }
  42. }
  43.  
  44. private int index;
  45. private Chopstick chopsticks;
  46.  
  47. public Philosopher(int index, Chopstick chopsticks) {
  48. this.index = index;
  49. this.chopsticks = chopsticks;
  50. }
  51.  
  52. private void think() {
  53. System.out.println(String.format("--哲学家%d--正在思考...", index));
  54. try {
  55. Thread.sleep(random(20 * 1000, 30 * 1000));
  56. } catch (InterruptedException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60.  
  61. private void eat() {
  62. System.out.println(String.format("--哲学家%d--正在吃饭...", index));
  63. try {
  64. Thread.sleep(random(20 * 1000, 30 * 1000));
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69.  
  70. @Override
  71. public void run() {
  72. while (true) {
  73. think();
  74. chopsticks.take_two(index);
  75. eat();
  76. chopsticks.put_two(index);
  77. }
  78. }
  79.  
  80. private static int random(int min, int max) {
  81. return min + (int) (Math.random() * (max - min + 1));
  82. }
  83.  
  84. public static void main(String[] args) {
  85. Chopstick chopsticks = new Chopstick();
  86. Philosopher p1 = new Philosopher(0, chopsticks);
  87. Philosopher p2 = new Philosopher(1, chopsticks);
  88. Philosopher p3 = new Philosopher(2, chopsticks);
  89. Philosopher p4 = new Philosopher(3, chopsticks);
  90. Philosopher p5 = new Philosopher(4, chopsticks);
  91. ExecutorService executorService = Executors.newCachedThreadPool();
  92. executorService.execute(p1);
  93. executorService.execute(p2);
  94. executorService.execute(p3);
  95. executorService.execute(p4);
  96. executorService.execute(p5);
  97. }
  98. }

进程同步——哲学家进餐问题Java实现的更多相关文章

  1. java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合

    关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...

  2. Java哲学家进餐问题|多线程

    Java实验三 多线程 哲学家进餐问题: 5个哲学家共用一张圆桌,分别坐在周围的5张椅子上, 在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双), 碗和筷子交替排列.他们的生活方式是交替地进行思考 ...

  3. 哲学家就餐问题-Java语言实现死锁避免

    哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...

  4. 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题

    首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...

  5. 第4章 同步控制 Synchronization ---哲学家进餐问题(The Dining Philosophers)

    哲学家进餐问题是这样子的:好几位哲学家围绕着餐桌坐,每一位哲学家要么思考,要么等待,要么就吃饭.为了吃饭,哲学家必须拿起两支筷子(分放于左右两端).不幸的是,筷子的数量和哲学家相等,所以每支筷子必须由 ...

  6. linux c语言 哲学家进餐---信号量PV方法一

    1.实验原理   由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题.该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的 ...

  7. Java 哲学家进餐

    某次操作系统实验存档.V 这个哲学家除了吃就知道睡.( ╯□╰ ) 哲学家.java: package operating.entity.philosophyeating; import operat ...

  8. 课程设计——利用信号量实现哲学家进餐问题(JAVA)

    package cn.Douzi.PhiEat; /** * 表示筷子的类 */ public class Chopstick{ /** * 表示筷子是否可用 */ private volatile ...

  9. Java哲学家进餐

    某次操作系统实验存档. 这个哲学家除了吃就是睡.. 哲学家.java: package operating.entity.philosophyeating; import operating.meth ...

随机推荐

  1. 【agc001d】Arrays and Palindrome

    Portal -->agc001D Description 给你一个\(m\)个数的排列\(A\),这个\(A\)中元素的顺序可以随便调换,\(A\)中的元素的和为\(n\),现在要你构造一个数 ...

  2. Hadoop基础-HDFS的读取与写入过程

    Hadoop基础-HDFS的读取与写入过程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 为了了解客户端及与之交互的HDFS,NameNode和DataNode之间的数据流是什么样 ...

  3. NOI2006 最大获利(最大权闭合子图)

    codevs 1789 最大获利 2006年NOI全国竞赛  时间限制: 2 s  空间限制: 128000 KB   题目描述 Description 新的技术正冲击着手机通讯市场,对于各大运营商来 ...

  4. SQL语句(十九)——存储过程(练习)

    select * From Student select * From Course select * from SC --INSERT INTO SC (Sno, Cno, Grade) --VAL ...

  5. EM算法(Expectation Maximization Algorithm)

    EM算法(Expectation Maximization Algorithm) 1. 前言   这是本人写的第一篇博客(2013年4月5日发在cnblogs上,现在迁移过来),是学习李航老师的< ...

  6. Centos7一键编译安装zabbix-4.0.2

    ##只针对centos7的系统有效,centos6无效,mysql zabbix用户:zabbix,密码:zabbix;建议用全新的centos7服务器 软件版本: (nginx-1.14.2.php ...

  7. Redis学习四:解析配置文件 redis.conf

    一.它在哪 地址: 思考:为什么要将它拷贝出来单独执行? 二.Units单位 1 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit 2 对大小写不敏感 三.INCLUDES包 ...

  8. Java并发编程原理与实战二十八:信号量Semaphore

    1.Semaphore简介 Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类. 所谓Semaphore即 信号量 的意思. 这个叫法并不能很好地 ...

  9. Java并发编程原理与实战十七:AQS实现重入锁

    一.什么是重入锁 可重入锁就是当前持有锁的线程能够多次获取该锁,无需等待 二.什么是AQS AQS是JDK1.5提供的一个基于FIFO等待队列实现的一个用于实现同步器的基础框架,这个基础框架的重要性可 ...

  10. php设计模式之六大设计原则

      1.单一职责 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 场景:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致 ...