黑马程序员_同步过程的死锁问题(哲学家难题)
2015-04-27 00:31
274 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。即使没有死锁,也有可能发生资源耗尽。例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
哲学家问题的Java 程序实现:
classzhangsan
{
public void say()
{
System.out.println("张三对李四说你给我画我就给你书");
}
public void get()
{
System.out.println("张三得到画");
}
}
classlisi
{
public void say()
{
System.out.println("李四对张三说你给我书我就给你画");
}
public void get()
{
System.out.println("李四得到书");
}
}
publicclass ThreadDemo implements Runnable
{
private static zhangsan zs=new zhangsan();
private static lisi ls=new lisi();
private boolean flag=false;
public void run()
{
if(flag)
{
synchronized(zs){
zs.say();
try{
Thread.sleep(200);//所有的
}catch(InterruptedException e ){
e.printStackTrace();
}
synchronized(ls){
zs.get();
}
}
}
else
{
synchronized(ls){
ls.say();
try{
Thread.sleep(200);
}catch(InterruptedException e ){
e.printStackTrace();
}
synchronized(zs){
ls.get();
}
}
}
}
publicstatic void main(String[] args)
{
ThreadDemo t1=new ThreadDemo();
ThreadDemo t2=new ThreadDemo();
t1.flag=true;
t2.flag=false;
Thread tha=new Thread(t1);
Thread thb=new Thread(t2);
tha.start();
thb.start();
}
}
程序的运行结果如下:
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。即使没有死锁,也有可能发生资源耗尽。例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
哲学家问题的Java 程序实现:
classzhangsan
{
public void say()
{
System.out.println("张三对李四说你给我画我就给你书");
}
public void get()
{
System.out.println("张三得到画");
}
}
classlisi
{
public void say()
{
System.out.println("李四对张三说你给我书我就给你画");
}
public void get()
{
System.out.println("李四得到书");
}
}
publicclass ThreadDemo implements Runnable
{
private static zhangsan zs=new zhangsan();
private static lisi ls=new lisi();
private boolean flag=false;
public void run()
{
if(flag)
{
synchronized(zs){
zs.say();
try{
Thread.sleep(200);//所有的
}catch(InterruptedException e ){
e.printStackTrace();
}
synchronized(ls){
zs.get();
}
}
}
else
{
synchronized(ls){
ls.say();
try{
Thread.sleep(200);
}catch(InterruptedException e ){
e.printStackTrace();
}
synchronized(zs){
ls.get();
}
}
}
}
publicstatic void main(String[] args)
{
ThreadDemo t1=new ThreadDemo();
ThreadDemo t2=new ThreadDemo();
t1.flag=true;
t2.flag=false;
Thread tha=new Thread(t1);
Thread thb=new Thread(t2);
tha.start();
thb.start();
}
}
程序的运行结果如下:
相关文章推荐
- uc笔记12---竞争与同步,互斥量,信号量,死锁,条件变量,哲学家就餐问题
- 黑马程序员----多线程2(安全问题、同步代码块、同步函数、死锁)
- 进程同步互斥——不死锁的哲学家问题
- Java总结(十)—实现Runnable接口创建线程,线程安全同步,死锁(哲学家进餐问题),读写锁
- 操作系统清华向勇陈渝版笔记(九) 同步协同多道程序设计和并发问题,同步互斥,死锁,临界区
- 进程的同步与互斥-哲学家问题
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 操作系统清华大学版笔记(十) 信号量、管程、条件互斥、经典同步问题(读者写者、哲学家问题)
- 黑马程序员----关于死锁的问题
- 经典同步问题(二)---哲学家就餐问题
- 黑马程序员--谈谈哲学家就餐的问题
- 黑马程序员_多线程之同步问题的前期,以及安全问题的发现和解决
- 同步和互斥的一些问题(死锁,优先级逆转)
- 如何防止哲学家就餐问题而引起的死锁
- 同步队列的死锁问题
- 线程问题——同步和死锁
- 睡觉理发师问题——进程同步与死锁
- 一个罕见的MySQL redo死锁问题排查及解决过程(pt-pmp)
- 黑马程序员——11,多线程,同步函数,死锁,一些零散的小知识点
- 死锁—哲学家吃饭问题