哲学家就餐问题

java多线程(八)-死锁问题和java多线程总结

十年热恋 提交于 2020-03-06 00:46:09
为了防止对共享受限资源的争夺,我们可以通过synchronized等方式来加锁,这个时候该线程就处于阻塞状态,设想这样一种情况,线程A等着线程B完成后才能执行,而线程B又等着线程C,而线程C又等着线程A。这三个任务之间相互循环等待,但是其实没有哪个任务能够执行,这种情况就发生了死锁。 有一个经典的哲学家就餐问题,可以更清晰的理解死锁问题。有N个哲学家围绕在一张圆形餐桌前,餐桌中间有一份面条,每个哲学家都只有一根筷子,放在他的左手边。(因为餐桌是圆形的,所以就是每两个哲学家之间有一根筷子),所以共计有N个哲学家,N个筷子, 哲学们家们有时候思考,思考时不需要获取其他共享资源;有时候吃面条,吃面条时需要两根筷子,哲学家需要先拿到他right手边的筷子,然后再去拿left手边的筷子。如果此时,left手边筷子不在桌子上(被边上的哲学家拿走了)。则哲学家就把right手边的筷子拿在手中等待。 (调用wait).等待left边的筷子被放下。如果哲学家吃完面条,则放下两根筷子 ,继续思考。 我们仅仅通过逻辑思考,就可以想到如果每个哲学家都拿到了他right手边的筷子,那么此时就发生了死锁,因为实际上桌子上,每个哲学家正好拿到了一根筷子,都在等待他left手边的筷子被放下,但是不会再有筷子被放下了. 代码demo:src\thread_runnable

java中的死锁问题研究

江枫思渺然 提交于 2020-03-01 05:03:29
1.什么是死锁: 百度百科的定义: 所谓死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 java中死锁:某个任务在等待另一个任务释放锁,而后者又等待别的任务释放锁,这样一直下去,直到这个链上的任务又在等待第一个任务释放锁,这得到了一个任务之间的相互等待的连续循环,没有哪个线程能继续,这被称之为死锁。 2.经典的死锁现象---哲学家就餐问题 由Edsger Dijkstra提出的哲学家就餐问题是一个经典的死锁例证。 哲学家就餐问题描述: 设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间很多食物,每两个哲学家之间有一只筷子。当一个哲学家要就餐的时候,这个哲学家必须同时得到左边和右边的筷子,如果一个哲学家左边或右边已经有人在使用筷子,那么这个哲学家就必须等待,直到得到必需的筷子。 下面就是哲学家就餐问题的java编写的程序: a.筷子类 public class Chopstick { private boolean taken = false; public synchronized void take() throws

PV经典问题之哲学家问题

十年热恋 提交于 2020-01-25 11:10:59
问题描述 (由Dijkstra首先提出并解决)5个哲学家围绕一张圆桌而坐,桌子上放着5支筷子, 每两个哲学家之间放一支;哲学家的动作包括思考和进餐,进餐时需要同时拿起他左 边和右边的两支筷子,思考时则同时将两支筷子放回原处。如何保证哲学家们的动作 有序进行?如:不出现相邻者同时要求进餐;不出现有人永远拿不到筷子。 关系分析。系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系。 整理思路。这个问题中只有互斥关系,但与之前 遇到的问题不同的事,每个哲学家进程需要同时 持有两个临界资源才能开始吃饭。如何避免临界 资源分配不当造成的死锁现象,是哲学家问题的精髓。 解决⽅法有两个,⼀个是让他们同时拿两个筷⼦:⼆是对每个哲学家的动作制定规则,避免饥饿或者死锁 。 ⽅法⼀: ⾄多只允许四位哲学家同时去拿左筷⼦,最终能保证⾄少有⼀位哲学家能进餐,并在⽤完后释放两只筷⼦供他⼈使⽤。 设置⼀个初值为 4 的信号量 r,只允许 4 个哲学家同时去拿左筷⼦,这样就能保证⾄少有⼀个哲学家可以就餐,不会出现饿死和死锁的现象。 原理 :⾄多只允许四个哲学家同时进餐,以保证⾄少有⼀个哲学家能够进餐,最终总会释放出他所使⽤过的两⽀筷⼦,从⽽可使更多的哲学家进餐。 代码如下: semaphore chopstick [ 5 ] = { 1 , 1 , 1 , 1 , 1 } ;

哲学家就餐问题、银行家算法、读者写者问题、生产者消费者问题

好久不见. 提交于 2020-01-25 00:29:04
哲学家就餐问题、银行家算法、读者写者问题、生产者消费者问题 哲学家就餐问题 解题思路 问题解决 方法一 方法二 方法三 银行家算法 安全状态 银行家算法的数据结构 银行家算法 安全性算法 银行家算法实例 读者写者问题 方法1:利用记录型信号量解决读者--写者问题 方法2:利用信号量集解决读者--写者问题 生产者消费者问题 哲学家就餐问题 该问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替的进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。 解题思路 因为是五位哲学家,并且每位哲学家的各自做自己的事情(思考和吃饭),因此可以创建五个线程表示五位哲学家,五个线程相互独立(异步)。并对五位哲学家分别编号为0~4。 ​ 同时,有五根筷子,每根筷子只对其相邻的两位哲学家是共享的,因此这五根筷子可以看做是五种不同的临界资源(不是一种资源有5个,因为每根筷子只能被固定编号的哲学家使用)。并对五根筷子分别编号为0~4,其中第i号哲学家左边的筷子编号为i,则其右边的筷子编号就应该为(i + 1) % 5。 ​ 因为筷子是临界资源,因此当一个线程在使用某根筷子的时候,应该给这根筷子加锁,使其不能被其他进程使用。 ​ 根据以上分析,可以使用pthread

通过锁对象解决哲学家就餐问题

旧时模样 提交于 2020-01-10 12:59:55
问题描述 哲学家进餐问题:5个哲学家共用一张圆桌,分别坐在周围的5张椅子上,在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双),碗和筷子交替排列。他们的生活方式是交替地进行思考(thinking)和进餐(eating)。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的两只筷子,规定他必须先取左边的筷子,再取右边的筷子。只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续进行思考。假如5位哲学家同时饥饿,各自拿起左边的筷子时,再去拿各自右边的筷子,因为无筷子可拿而陷入无期限等待(死锁)。一种解决的办法是:至多只允许有4位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够拿到两只筷子,从而进餐。进餐完毕释放他用过的两只筷子,从而使更多的哲学家能够进餐。使用Java的多线程同步技术,实现上述解决方案。 主方法 package cn.learn.thread.ThreadState.practice; //测试 public class Test { public static void main(String[] args) { //五根筷子对象 Chopsticks[] chopsticks = new Chopsticks[5]; for (int i = 0; i <5 ; i++) { chopsticks[i] = new Chopsticks("--

哲学家进餐问题

好久不见. 提交于 2020-01-10 00:32:51
参考:https://blog.csdn.net/fuziwang/article/details/79809994 1.问题描述: 哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。 约束条件 (1)只有拿到两只筷子时,哲学家才能吃饭。 (2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。 (3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。 2.求解方法 (1).信号量的设置 放在桌子上的筷子是临界资源,在一段时间内 只允许一位哲学家 使用,为了实现对筷子的互斥访问,可以用一个信号量表示筷子,由这 五个信号量构成信号量数组 。 semaphore chopstick[5] = {1,1,1,1,1}; while(true) { /*当哲学家饥饿时,总是先拿左边的筷子,再拿右边的筷子*/ wait(chopstick[i]); wait(chopstick[(i+1)%5]); // 吃饭 /*当哲学家进餐完成后,总是先放下左边的筷子,再放下右边的筷子*/ signal(chopstick[i]); signal

死锁与哲学家就餐问题

有些话、适合烂在心里 提交于 2019-11-26 10:29:34
设计一 采用预先分配法预防死锁的哲学家就餐问题 1. 实验目的 理解死锁的概念,掌握死锁预防方法。 死锁是进程并发执行过程中可能出现的现象,哲学家就餐问题是描述死锁的经典例子。为了防止死锁,可以采用资源预先分配法。资源预先分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。在哲学家就餐问题中,要采用资源预先分配法只需让每个哲学家同时申请左右两根筷子。 2. 实验要求 利用多线程技术编写哲学家就餐程序,演示采用死锁防止方法后不产生死锁的情况。 3. 实验步骤 3.1 程序结构设计 程序需要六个线程,主线程用于显示功能描述;五个哲学家线程用于模拟哲学家的活动,即不停地思考、饥饿、进食。相邻的两个哲学家线程需要共享他们中间的同一根筷子,因此对每一根筷子的使用要互斥,用互斥体数组h_mutex_chopsticks来实现。主线程创建五个哲学家线程后要等待所有哲学家结束,用线程句柄数组h_thread来表示五个线程,主线程通过等待这五个线程句柄来实现同步。 该程序共有7个函数,这些函数可以分成4组。各组包含的函数及其功能如图4-1所示。 组别 包括函数 函数功能 一 main() 显示主菜单,接收用户的选择并执行相应的功能