JAVA多线程学习--哲学家就餐问题
哲学家就餐问题是1965年由Dijkstra提出的一种线程同步的问题。
问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。
解决办法:
1、添加一个服务生,只有当经过服务生同意之后才能拿筷子,服务生负责避免死锁发生。
2、每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子。
3、规定每个哲学家拿筷子时必须拿序号小的那只,这样最后一位未拿到筷子的哲学家只剩下序号大的那只筷子,不能拿起,剩下的这只筷子就可以被其他哲学家使用,避免了死锁。这种情况不能很好的利用资源。
代码实现:实现第2种方案
package cn.edu.sdust.Philosopher; /*每个哲学家相当于一个线程*/
class Philosopher extends Thread{
private String name;
private Fork fork;
public Philosopher(String name,Fork fork){
super(name);
this.name=name;
this.fork=fork;
} public void run(){
while(true){
thinking();
fork.takeFork();
eating();
fork.putFork();
} } public void eating(){
System.out.println("I am Eating:"+name);
try {
sleep();//模拟吃饭,占用一段时间资源
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void thinking(){
System.out.println("I am Thinking:"+name);
try {
sleep();//模拟思考
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} class Fork{
/*5只筷子,初始为都未被用*/
private boolean[] used={false,false,false,false,false,false}; /*只有当左右手的筷子都未被使用时,才允许获取筷子,且必须同时获取左右手筷子*/
public synchronized void takeFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
while(used[i]||used[(i+)%]){
try {
wait();//如果左右手有一只正被使用,等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
used[i ]= true;
used[(i+)%]=true;
} /*必须同时释放左右手的筷子*/
public synchronized void putFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name); used[i ]= false;
used[(i+)%]=false;
notifyAll();//唤醒其他线程
}
} //测试
public class ThreadTest { public static void main(String []args){
Fork fork = new Fork();
new Philosopher("",fork).start();
new Philosopher("",fork).start();
new Philosopher("",fork).start();
new Philosopher("",fork).start();
new Philosopher("",fork).start();
}
}
运行结果:
I am Thinking:
I am Thinking:
I am Thinking:
I am Thinking:
I am Thinking:
I am Eating:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
I am Eating:
I am Thinking:
。。。。。。。。。。。。。
分析:上述解决方案解决了死锁问题。可以看到最多只能有两条相邻的eating结果,因为每个时刻最多能够满足两个人同时进餐,且两人座位不相邻。
JAVA多线程学习--哲学家就餐问题的更多相关文章
- Java多线程,哲学家就餐问题
问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.上述问题会产生死锁的情况,当5个哲学家都拿起自己右手 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习(转载)
Java多线程学习(转载) 时间:2015-03-14 13:53:14 阅读:137413 评论:4 收藏:3 [点我收藏+] 转载 :http://blog ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- 【转】Java多线程学习
来源:http://www.cnblogs.com/samzeng/p/3546084.html Java多线程学习总结--线程概述及创建线程的方式(1) 在Java开发中,多线程是很常用的,用得好的 ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习(六)Lock锁的使用
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(五)线程间通信知识点补充
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(四)等待/通知(wait/notify)机制
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
随机推荐
- Django之牛逼的Models
Django里的模型是对数据库对表的一次封装,是应用业务与数据之间的桥梁 要想使用Django的models 首先得配置settings Django默认使用的是sqlite,我使用的Mysql,配置 ...
- ios uitableviewcell动态计算高度
#import <UIKit/UIKit.h> @interface TestCell : UITableViewCell @property (weak, nonatomic) IBOu ...
- 【Shell脚本学习2】Shell脚本语言与编译型语言的差异
大体上,可以将程序设计语言可以分为两类:编译型语言和解释型语言. 编译型语言 很多传统的程序设计语言,例如Fortran.Ada.Pascal.C.C++和Java,都是编译型语言.这类语言需要预先将 ...
- 【Android 界面效果14】RelativeLayout里常用的位置属性
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- android:layout_toLeftOf—— 该组件位于引用组件的左方 android:layou ...
- Gradle实战:发布aar包到maven仓库
查看原文:http://blog.csdn.net/u010818425/article/details/52441711 Gradle实战系列文章: <Gradle基本知识点与常用配置> ...
- 给定数组a[N]构造数组b[N]
转自:http://blog.csdn.net/wumuzi520/article/details/7841280 给定一个数组a[N],我们希望构造数组b [N], 其中b[j]=a[0]*a[1] ...
- 转:eclipse技巧之快速生成Override函数
转自: http://www.cnblogs.com/junqilian/archive/2013/03/15/2960277.html 小提示:Eclipse 中快速实现或Override基类或接口 ...
- 一步步搭建自己的轻量级MVCphp框架-(四)一个国产轻量级框架Amysql源码分析(3) 总进程对象
AmysqlProcess类,框架的总进程对象 ./Amysql/Amysql.php 下面还是和以前一样,先上代码~ class AmysqlProcess { public $AmysqlCont ...
- kettle菜鸟学习笔记3----kettle数据库连接错误及解决
数据库连接测试时,所有的参数信息都填写正确,却报错了. 或者,没有进行数据库连接测试,直接保存了当前数据库连接,然后在浏览,选择目标表时报错: 或者其他别的关于数据库连接的错误…… 第一个要考虑的就是 ...
- Hive通过查询语句向表中插入数据注意事项
最近在学习使用Hive(版本0.13.1)的过程中,发现了一些坑,它们或许是Hive提倡的比关系数据库更加自由的体现(同时引来一些问题),或许是一些bug.总而言之,这些都需要使用Hive的开发人员额 ...