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

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

解决办法:

  • 拿筷子之前判断两支筷子是否有人使用,都无人使用时才能拿起筷子。
  • 不能独占一支筷子,造成死锁。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Philosopher implements Runnable { private static class Chopstick {
private boolean[] chopsticks = {true, true, true, true, true}; public synchronized void take_two(int index) {
while (!attempt(index)) {
System.out.println(String.format("--哲学家%d--尝试拿筷子--失败...", index));
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(String.format("--哲学家%d--尝试拿筷子--成功...", index));
chopsticks[getLeft(index)] = false;
chopsticks[getRight(index)] = false;
} private boolean attempt(int index) {
System.out.println(String.format("--哲学家%d--尝试拿筷子...", index));
return chopsticks[getLeft(index)] && chopsticks[getRight(index)];
} public synchronized void put_two(int index) {
System.out.println(String.format("--哲学家%d--放下筷子...", index));
chopsticks[getLeft(index)] = true;
chopsticks[getRight(index)] = true;
notifyAll();
} int getLeft(int index) {
return (index - 1 + chopsticks.length) % chopsticks.length;
} int getRight(int index) {
return index;
}
} private int index;
private Chopstick chopsticks; public Philosopher(int index, Chopstick chopsticks) {
this.index = index;
this.chopsticks = chopsticks;
} private void think() {
System.out.println(String.format("--哲学家%d--正在思考...", index));
try {
Thread.sleep(random(20 * 1000, 30 * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void eat() {
System.out.println(String.format("--哲学家%d--正在吃饭...", index));
try {
Thread.sleep(random(20 * 1000, 30 * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override
public void run() {
while (true) {
think();
chopsticks.take_two(index);
eat();
chopsticks.put_two(index);
}
} private static int random(int min, int max) {
return min + (int) (Math.random() * (max - min + 1));
} public static void main(String[] args) {
Chopstick chopsticks = new Chopstick();
Philosopher p1 = new Philosopher(0, chopsticks);
Philosopher p2 = new Philosopher(1, chopsticks);
Philosopher p3 = new Philosopher(2, chopsticks);
Philosopher p4 = new Philosopher(3, chopsticks);
Philosopher p5 = new Philosopher(4, chopsticks);
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(p1);
executorService.execute(p2);
executorService.execute(p3);
executorService.execute(p4);
executorService.execute(p5);
}
}

进程同步——哲学家进餐问题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. 【最小割】【网络流24题】【P2762】 太空飞行计划问题

    Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,-,Em},和进行这些实验需要使 ...

  2. poi excel导入纯数字单元格显示科学计数法的处理

    POI读取Excel文件时,对纯数字单元格的处理   用POI读取Excel文件的时候,可能会遇到这样的问题:Excel文件中某一单元格中的数据为数字,例如12345678910123. 正常读取的话 ...

  3. python定义函数以及参数检查

    (转自廖雪峰网站) 函数定义 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 我们以自定义 ...

  4. C++ explicit constructor/copy constructor note

    C++:explict 作用显示声明构造函数只能被显示调用从而阻止编译器的隐式转换,类似只能用()显示调用,而不能=或者隐式调用 #include <iostream> #include ...

  5. js 读写 cookie 简单实现

    const getItem = key => { let ca = document.cookie.split('; '); for (let i = 0; i < ca.length; ...

  6. Lowest Common Ancestor in a Binary Tree

    二叉树最低公共祖先节点 acmblog If one key is present and other is absent, then it returns the present key as LC ...

  7. Python 字符串前面加u,r,b的含义

    1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...

  8. Unity官方实例教程 Roll-a-Ball

    与unity的transform组件相处的挺久了,最近项目不太忙,决定好好打下unity的基础.那么从Roll-a-Ball这个简单游戏开始吧! 1.先创建一个球体游戏对象,改名为Player,tra ...

  9. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第四部分(Page 9)

    编写你的第一个 Django app,第四部分(Page 9)转载请注明链接地址 该教程上接前面的第三部分.我们会继续开发 web-poll 应用,并专注于简单的表单处理和简化代码. 写一个简单的表单 ...

  10. 正则表达式&自定义异常 典型案例

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test { public static vo ...