进程同步——哲学家进餐问题Java实现
哲学家就餐问题是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实现的更多相关文章
- java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合
关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...
- Java哲学家进餐问题|多线程
Java实验三 多线程 哲学家进餐问题: 5个哲学家共用一张圆桌,分别坐在周围的5张椅子上, 在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双), 碗和筷子交替排列.他们的生活方式是交替地进行思考 ...
- 哲学家就餐问题-Java语言实现死锁避免
哲学家就餐问题-Java语言实现死锁避免 我死锁预防是至少破坏死锁产生的四个必要条件之一,带来的问题就是系统资源利用率低且不符合开发习惯,而死锁避免不是事先釆取某种限制措施破坏死锁的必要条件,只是注意 ...
- 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题
首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...
- 第4章 同步控制 Synchronization ---哲学家进餐问题(The Dining Philosophers)
哲学家进餐问题是这样子的:好几位哲学家围绕着餐桌坐,每一位哲学家要么思考,要么等待,要么就吃饭.为了吃饭,哲学家必须拿起两支筷子(分放于左右两端).不幸的是,筷子的数量和哲学家相等,所以每支筷子必须由 ...
- linux c语言 哲学家进餐---信号量PV方法一
1.实验原理 由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题.该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的 ...
- Java 哲学家进餐
某次操作系统实验存档.V 这个哲学家除了吃就知道睡.( ╯□╰ ) 哲学家.java: package operating.entity.philosophyeating; import operat ...
- 课程设计——利用信号量实现哲学家进餐问题(JAVA)
package cn.Douzi.PhiEat; /** * 表示筷子的类 */ public class Chopstick{ /** * 表示筷子是否可用 */ private volatile ...
- Java哲学家进餐
某次操作系统实验存档. 这个哲学家除了吃就是睡.. 哲学家.java: package operating.entity.philosophyeating; import operating.meth ...
随机推荐
- fzyzojP3412 -- [校内训练20171212]奇数
套路地, 考虑dfs树上搞事情 容易发现,对于(x,y)如果dfs树上距离为奇数,或者dfs树上路径中有一条边在某个简单奇环上,那么可以经过奇数条边到达 判断边在某个奇环上: 点双,点双中黑白染色,如 ...
- Spring MVC使用Cors实现跨域
在开发APP过程中,APP调用后端接口有跨域的问题,只要在spring-mvc.xml 文件中加入下面的配置即可: <!-- 解决API接口跨域问题配置 Spring MVC 版本必须是 4.2 ...
- 六、java异常处理
目录 一.异常的概念 二.异常的分类 三.异常的捕获和处理 四.使用自定义异常 一.异常的概念 java异常是指java提供的用于处理程序运行过程中错误的一种机制 所谓错误是指在程序运行的过程中发生的 ...
- numpy/arrayobject.h”: No such file or directory
import numpyimport pyximportpyximport.install(setup_args={"script_args":["--compiler= ...
- Java基础-面向对象第二特征之继承(Inheritance)
Java基础-面向对象第二特征之继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承的概述 在现实生活中,继承一般指的是子女继承父辈的财产.在程序 ...
- Dubbo学习笔记2:Dubbo服务提供端与消费端应用的搭建
Demo结构介绍 Demo使用Maven聚合功能,里面有三个模块,目录如下: 其中Consumer模块为服务消费者,里面TestConsumer和consumer.xml组成了基于Spring配置方式 ...
- Zabbix监控PV和UV
Zabbix-server:172.21.97.153 Zabbix-agent(Nginx):172.17.27.61 # Nginx日志如下: # head -3 Syz.access.log w ...
- Java 避免精度丢失之BigDecimal 运算
* 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入 import java.math.BigDecimal; /** 计算工具类 */ pu ...
- activity 中获取控件的宽高
1.第一种方式: TextView textview3 = findViewById(R.id.textview3); textView3.post(new Runnable() { @Overrid ...
- IOC轻量级框架之Unity
任何事物的出现,总有它独特的原因,Unity也是如此,在Unity产生之前,我们是这么做的 我们需要在一个类A中引用另一个类B的时候,总是将类B的实例放置到类A的构造函数中,以便在初始化类A的时候,得 ...