java中哲學家就餐死鎖_哲學家就餐問題與死鎖總結

死鎖的四個條件:

(1) 互斥條件:一個資源每次只能被一個進程使用。

(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系

先寫一個會造成死鎖的哲學家問題。當所有哲學家同時決定進餐,拿起左邊筷子時候,就發生了死鎖。

public class test {

public static void main(String[] args) {

ExecutorService exec = Executors.newCachedThreadPool();

int sum = 5;

Chopstick[] chopsticks = new Chopstick[sum];

for (int i = 0; i < sum; i++) {

chopsticks[i] = new Chopstick();

}

for (int i = 0; i < sum; i++) {

exec.execute(new Philosopher(chopsticks[i], chopsticks[(i + 1) % sum]));

}

}

}

// 筷子

class Chopstick {

public Chopstick() {

}

}

class Philosopher implements Runnable {

private Chopstick left;

private Chopstick right;

public Philosopher(Chopstick left, Chopstick right) {

this.left = left;

this.right = right;

}

@Override

public void run() {

try {

while (true) {

Thread.sleep(1000);//思考一段時間

synchronized (left) {

synchronized (right) {

Thread.sleep(1000);//進餐一段時間

}

}

}

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

解決方案一:破壞死鎖的循環等待條件。

不再按左手邊右手邊順序拿起筷子。選擇一個固定的全局順序獲取,此處給筷子添加id,根據id從小到大獲取,(不用關心編號的具體規則,只要保證編號是全局唯一并且有序的),不會出現死鎖情況。

public class test {

public static void main(String[] args) {

ExecutorService exec = Executors.newCachedThreadPool();

int sum = 5;

Chopstick[] chopsticks = new Chopstick[sum];

for (int i = 0; i < sum; i++) {

chopsticks[i] = new Chopstick(i);

}

for (int i = 0; i < sum; i++) {

exec.execute(new Philosopher(chopsticks[i], chopsticks[(i + 1) % sum]));

}

}

}

// 筷子

class Chopstick {

//狀態

private int id;

public Chopstick(int id) {

this.id=id;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

}

// 哲學家

class Philosopher implements Runnable {

private Chopstick left;

private Chopstick right;

public Philosopher(Chopstick left, Chopstick right) {

if(left.getId()

this.left = left;this.right = right;

}else{

this.left=right;this.right=left;

}

}

@Override

public void run() {

try {

while (true) {

Thread.sleep(1000);//思考一段時間

synchronized (left) {

synchronized (right) {

Thread.sleep(1000);//進餐一段時間

}

}

}

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

方法二:破壞死鎖的請求與保持條件,使用lock的特性,為獲取鎖操作設置超時時間。這樣不會死鎖(至少不會無盡的死鎖)

class Philosopher extends Thread{

private ReentrantLock left,right;

public Philosopher(ReentrantLock left, ReentrantLock right) {

super();

this.left = left;

this.right = right;

}

public void run(){

try {

while(true){

Thread.sleep(1000);//思考一段時間

left.lock();

try{

if(right.tryLock(1000,TimeUnit.MILLISECONDS)){

try{

Thread.sleep(1000);//進餐一段時間

}finally {

right.unlock();

}

}else{

//沒有獲取到右手的筷子,放棄并繼續思考

}

}finally {

left.unlock();

}

}

} catch (InterruptedException e) {

}

}

}

方法三:設置一個條件遍歷與一個鎖關聯。該方法只用一把鎖,沒有chopstick類,將競爭從對筷子的爭奪轉換成了對狀態的判斷。僅當左右鄰座都沒有進餐時才可以進餐。提升了并發度。前面的方法出現情況是:只有一個哲學家進餐,其他人持有一根筷子在等待另外一根。這個方案中,當一個哲學家理論上可以進餐(鄰座沒有進餐),他肯定可以進餐。

public class Philosopher extends Thread{

private boolean eating;

private Philosopher left;

private Philosopher right;

private ReentrantLock lock;

private Condition condition;

public Philosopher(ReentrantLock lock){

eating =false;

this.lock=lock;

condition=lock.newCondition();

}

public void setLeft(Philosopher left) {

this.left = left;

}

public void setRight(Philosopher right) {

this.right = right;

}

public void think() throws InterruptedException{

lock.lock();

try {

eating=false;

System.out.println(Thread.currentThread().getName()+"開始思考");

left.condition.signal();

right.condition.signal();

} finally{

lock.unlock();

}

Thread.sleep(1000);

}

public void eat() throws InterruptedException{

lock.lock();

try {

while(left.eating||right.eating)

condition.await();

System.out.println(Thread.currentThread().getName()+"開始吃飯");

eating=true;

} finally {

// TODO: handle finally clause

lock.unlock();

}

Thread.sleep(1000);

}

public void run(){

try{

while(true){

think();

eat();

}

}catch(InterruptedException e){}

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542688.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542688.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542688.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux掃描工具之nmap

Linux下有很多強大網絡掃描工具&#xff0c;網絡掃描工具可以分為&#xff1a;主機掃描、主機服務掃描、路由掃描等,nmap支持批量主機掃描和主機服務掃描。檢測安裝&#xff1a;[rootbier ~]# rpm -qa nmap nmap-5.51-4.el6.x86_64如果沒有安裝就安裝一下nmap的安裝直接使用&am…

如何將多個一維列表轉化為二維列表_數據分析2_如何處理一維、二維數據

吞一塊大餅&#xff0c;還不如切成小塊吃得香常見的數據集&#xff0c;要么是數列&#xff0c;要么是表格&#xff1b;因此&#xff0c;數據分析最首要的是&#xff0c;處理一維、二維數據。主要知識點可參考如圖。如需要&#xff0c;可點擊以下百度網盤鏈接下載數據分析基礎知…

關于java中鎖的面試題_Java面試題-Java中的鎖

1. 如何實現樂觀鎖(CAS)&#xff1f;如何避免ABA問題&#xff1f;答&#xff1a;1)讀取內存值的方式實現了樂觀鎖(比如&#xff1a;SVN系統)&#xff0c;方法&#xff1a;第一&#xff0c;比較內存值和期望值&#xff1b;第二&#xff0c;替換內存值為要替換值。2)帶參數版本來…

NSUserDefaults

2019獨角獸企業重金招聘Python工程師標準>>> NSUserDefaults 轉載于:https://my.oschina.net/18829297883/blog/737931

什么是算術運算和邏輯運算_8086微處理器的算術和邏輯運算

什么是算術運算和邏輯運算邏輯指令 (Logical Instructions) a) AND: Logical AND a)AND&#xff1a;邏輯AND Atleast one of the operant should be a register or a memory operant both the operant cannot be a memory location or immediate operant. 操作中的至少一個應該…

python文件讀寫用到的庫_Python使用pyshp庫讀取shapefile信息的方法

通過pyshp庫&#xff0c;可以讀寫shapefile文件&#xff0c;查詢相關信息&#xff0c;github地址為 import shapefile # 使用pyshp庫 file shapefile.reader("data\\市界.shp") shapes file.shapes() # print(file.shapetype) # 輸出shp類型null 0 point 1 poly…

h5引入json_Vue中如何使用本地Json文件?

我需要將菜單配置成Json文件&#xff0c;然后再程序中引入{{menu.name}}import menuListConfig from ../../config/menu.jsonexport default {name: "Sider",data(){return {menuList:JSON.parse(JSON.stringify(menuListConfig))}}}需要如何做&#xff0c;才能v-for…

深入學習jQuery選擇器系列第四篇——過濾選擇器之屬性選擇器

前面的話 屬性過濾選擇器的過濾規則是通過元素的屬性來獲取相應的元素&#xff0c;對應于CSS中的屬性選擇器。屬性過濾選擇器可分為簡單屬性選擇器、具體屬性選擇器和條件屬性選擇器三種。本文將詳細該部分內容 簡單屬性選擇器 [attribute] [attribute]選擇器選擇擁有該屬性的元…

c++ scanf讀取_使用scanf()讀取內存地址并在C中打印其值

c scanf讀取Here, we have to input a valid memory address and print the value stored at memory address in C. 在這里&#xff0c;我們必須輸入一個有效的內存地址并在C中打印存儲在內存地址中的值。 To input and print a memory address, we use "%p" format…

python正則匹配_Python正則表達式只匹配一次

我正在嘗試創建一個簡單的降價乳膠轉換器,只是為了學習 python和基本的正則表達式,但我不知道試圖弄清楚為什么下面的代碼不起作用&#xff1a; re.sub (r\[\*\](.*?)\[\*\]: ?(.*?)$, r\\footnote{\2}\1, s, flagsre.MULTILINE|re.DOTALL) 我想轉換像&#xff1a; s "…

Virtual Network (1) - How to use it in a guest

本文將講述一個問題&#xff1a;kvm guest使用libvirt xml定義如何使用virtual network&#xff1f;1&#xff09;nat&#xff0c; route &#xff0c;isolated, open類型在host中定義virtual network會創建一個虛擬的bridge&#xff0c;相當于一個交換機。guest只需要連接到這…

java string做除法_如果用java來實現傳統方式的除法,用String來保存結果,想精確多少位都行,那改怎么做?...

我會加分的&#xff0c;提個思路都行&#xff0c;目前做了個乘法和加法&#xff0c;但是現在對除法沒有什么思路。以下是我編寫的功能&#xff1a;publicclassCalculator{publicstaticStringmulti(Strings1,Strings2){if(s1nu...我會加分的&#xff0c;提個思路都行&#xff0c…

c語言數組的聲明和初始化_C聲明和初始化能力問題和解答

c語言數組的聲明和初始化This section contains aptitude questions and answers on C language Declarations and Initialization. 本節包含有關C語言聲明和初始化的適切性問題和解答。 1) What will be the output of following program ? int main(){int m10;int xprintf(…

python2和python3的默認編碼_python2和python3哪個版本新

Python2 還是 Python3 &#xff1f; py2.7是2.x系列的最后一個版本&#xff0c;已經停止開發&#xff0c;不再增加新功能。2020年終止支持。 所有的最新的標準庫的更新改進&#xff0c;只會在3.x的版本里出現。Python3.0在2008年就發布出來&#xff0c;而2.7作為2.X的最終版本并…

html-css樣式表

一、CSS&#xff1a;Cascading Style Sheet—層疊樣式表&#xff0c;其作用是美化HTML網頁。 樣式表分類&#xff1a;內聯樣式表、內嵌樣式表、外部樣式表 1、內聯樣式表 和HTML聯合顯示&#xff0c;控制精確&#xff0c;但是可重用性差&#xff0c;冗余多。 例如&#xff1a;&…

java 棧 先進后出_棧先進后出,堆先進先出

1.棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C不同&#xff0c;Java自動管理棧和堆&#xff0c;程序員不能直接地設置棧或堆。2.棧的優勢是&#xff0c;存取速度比堆要快&#xff0c;僅次于直接位于CPU中的寄存器。但缺點是&#xff0c;存在棧中的數據大小與生…

c#給定二維數組按升序排序_在數組中按升序對數字進行排序| 8086微處理器

c#給定二維數組按升序排序Problem: Write a program in 8086 microprocessor to sort numbers in ascending order in an array of n numbers, where size n is stored at memory address 2000 : 500 and the numbers are stored from memory address 2000 : 501. 問題&#xf…

使用python套用excel模板_Python自動化辦公Excel-從表中批量復制粘貼數據到新表

1、模塊安裝 1&#xff09;cmd模式下&#xff1a; pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xlrd pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl 2&#xff09;如果有安裝Pycharm&#xff0c;則在程序中操作如下&#xff1a; 菜單欄&…

在HubSpot是如何應對Fat JAR困境的

在七月底&#xff0c;Spring Boot和Dropwizard分別發布了1.4和1.0版本&#xff0c;它們都是基于Fat JAR的。隨著人們更多地采用這些框架和微服務架構&#xff0c;Fat JAR成為了通用的部署機制。\\Fat JAR技術會將Java應用的所有依賴打包到一個bundle之中&#xff0c;便于執行&a…

給定數字的b+樹創建_在C ++中找到給定數字中的兩個的下一個和上一個冪

給定數字的b樹創建Problem statement: 問題陳述&#xff1a; Find Next and previous power of two of a given number 查找給定數字中兩個的下一個和上一個冪 Next power of two 下一個二的冪 Example(1):input: 22output: 32 ( as 32 is 2^5)Example(2):input: 54output…