哲学家就餐问题是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. 目标检测应用化之web页面(YOLO、SSD等)

    在caffe源码目录下的examples下面有个web_demo演示代码,其使用python搭建了Flask web服务器进行ImageNet图像分类的演示. 首先安装python的依赖库:pip i ...

  2. 2018 CTSC&APIO 游记

    CTSC 居然是CTSC先考,弄得我有些意外. 5.6 早上5:30乘坐高铁来到北京,差不多下午了吧,具体几点忘记了,然后来到宾馆   试机也没有去,就直接在宾馆颓废了. 5.7 考试的第一天,6:3 ...

  3. linux操作系统位数

    方法1:getconf LONG_BIT 查看 如下例子所示: 32位Linux系统显示32, 64位Linux系统显示64.最简单.快捷的方法. [root@DB-Server ~]# getcon ...

  4. sqlalchemy多外键关联

    一.前言 如果有张表A的多个字段关联另一张表B的一个字段,就如同一个客户表的账单地址和发货地址,同时关联地址表中的id字段. 二.事例 # -*- coding: UTF-8 -*- from sql ...

  5. python的函数介绍 位置参数 关键字参数 默认参数 参数组 *args **kwargs

    1.数学意义的函数与python中的函数 数学意义的函数 y = 2*3+1 x =3 y =7 x是自变量,y是因变量 2.python中定义函数的方法 一个函数往往都是为了完成一个特定的功能而存在 ...

  6. Java基础-MySQL数据库扫盲篇

    Java基础-MySQL数据库扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据库概述 1>.什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按 ...

  7. c# string 和 byte[]数组之间转换

    在文件流读取和存储过程当中,经常涉及到byte[]数组形式存储数据,再此过程中也涉及到String类型字符串和byte[]的类型转换,下面我们举例说明一下. 现在有一个字符串: string str ...

  8. [Luogu 2169] 正则表达式

    [Luogu 2169] 正则表达式 感谢 0xis 推题. 记忆中很久没有过一遍写过一题了- 别被题目名称蒙骗!这不是正则表达式题目!和字符(串)处理一点关系都没有!这是个图论题啊喂! 题都没急,C ...

  9. ASP.NET中的另类控件

    首先看一个aspx文件里的部分内容: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  10. 33、Map简介

    Map接口概述 除了Collection之外,常用的集合还有Map接口,里面常用的实现类图如下: map中的元素是以键-值的方式存在的,通过键可以获取到值,键是不可以重复的,跟地图比较像,通过一个坐标 ...