进程同步——哲学家进餐问题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 ...
随机推荐
- linux命令总结sed命令详解
Sed 简介 sed 是一种新型的,非交互式的编辑器.它能执行与编辑器 vi 和 ex 相同的编辑任务.sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编辑命令.指定文件名,然后在屏幕上查 ...
- Windows 2012 R2 安装net4.6.1
下载并安装Net4.6.1 根据提示下载如下,并安装 https://support.microsoft.com/zh-cn/help/2919355/windows-rt-8-1--windows- ...
- tips 前端 bootstrap 嵌套行 嵌套列 溢出 宽度不正确 栅格化系统计算
bootstrap 当嵌套列时 有时会出现很奇异的row 的width不对问题出现的情况时 <div class="row" > <!--row a--> ...
- bzoj千题计划172:bzoj1192: [HNOI2006]鬼谷子的钱袋
http://www.lydsy.com/JudgeOnline/problem.php?id=1192 1,2,4,8,…… n-2^k 可以表示n以内的任意数 若n-2^k 和 之前的数相等,一个 ...
- 图论:LCA-欧拉序
#include<cmath> #include<vector> #include<cstdio> #include<cstring> #include ...
- Intellij IDEA设置及快捷键使用总结
1. IDEA内存优化 先看看你机器本身的配置而配置. \IntelliJ IDEA 8\bin\idea.exe.vmoptions -------------------------------- ...
- Java并发编程原理与实战三十八:多线程调度器(ScheduledThreadPoolExecutor)
在前面介绍了java的多线程的基本原理信息:线程池的原理与使用 本文对这个java本身的线程池的调度器做一个简单扩展,如果还没读过上一篇文章,建议读一下,因为这是调度器的核心组件部分. 我们如果要用j ...
- markdown里的多层次列表项
markdown里的多层次列表项 编写python的docstrng太多, 有时候就搞混淆了层次化列表项在博客或者随笔里的规则. docstirng里, 仅用两个空格的缩进就可以实现. 博客里通常是一 ...
- bzoj 2111 [ZJOI2010]Perm 排列计数(DP+lucas定理)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2111 [题意] 给定n,问1..n的排列中有多少个可以构成小根堆. [思路] 设f[i ...
- 学号20155308 2016-2017-2 《Java程序设计》第6周学习总结
学号20155308 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入与输出 目的:文件的读写:网络上传数据的基础:同样要掌握父类中方法. 10. ...