进程同步——哲学家进餐问题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 ...
随机推荐
- 【agc001d】Arrays and Palindrome
Portal -->agc001D Description 给你一个\(m\)个数的排列\(A\),这个\(A\)中元素的顺序可以随便调换,\(A\)中的元素的和为\(n\),现在要你构造一个数 ...
- Hadoop基础-HDFS的读取与写入过程
Hadoop基础-HDFS的读取与写入过程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 为了了解客户端及与之交互的HDFS,NameNode和DataNode之间的数据流是什么样 ...
- NOI2006 最大获利(最大权闭合子图)
codevs 1789 最大获利 2006年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目描述 Description 新的技术正冲击着手机通讯市场,对于各大运营商来 ...
- SQL语句(十九)——存储过程(练习)
select * From Student select * From Course select * from SC --INSERT INTO SC (Sno, Cno, Grade) --VAL ...
- EM算法(Expectation Maximization Algorithm)
EM算法(Expectation Maximization Algorithm) 1. 前言 这是本人写的第一篇博客(2013年4月5日发在cnblogs上,现在迁移过来),是学习李航老师的< ...
- Centos7一键编译安装zabbix-4.0.2
##只针对centos7的系统有效,centos6无效,mysql zabbix用户:zabbix,密码:zabbix;建议用全新的centos7服务器 软件版本: (nginx-1.14.2.php ...
- Redis学习四:解析配置文件 redis.conf
一.它在哪 地址: 思考:为什么要将它拷贝出来单独执行? 二.Units单位 1 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit 2 对大小写不敏感 三.INCLUDES包 ...
- Java并发编程原理与实战二十八:信号量Semaphore
1.Semaphore简介 Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类. 所谓Semaphore即 信号量 的意思. 这个叫法并不能很好地 ...
- Java并发编程原理与实战十七:AQS实现重入锁
一.什么是重入锁 可重入锁就是当前持有锁的线程能够多次获取该锁,无需等待 二.什么是AQS AQS是JDK1.5提供的一个基于FIFO等待队列实现的一个用于实现同步器的基础框架,这个基础框架的重要性可 ...
- php设计模式之六大设计原则
1.单一职责 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 场景:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致 ...