日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哲学家就餐与死锁问题,死锁产生的条件以及解决方案

發(fā)布時(shí)間:2025/3/20 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哲学家就餐与死锁问题,死锁产生的条件以及解决方案 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

請(qǐng)結(jié)合經(jīng)典案例-哲學(xué)家就餐,來談?wù)勀銓?duì)死鎖的理解,以及怎么預(yù)防和解除死鎖?


哲學(xué)家就餐

描述:在一張圓桌上,有n個(gè)哲學(xué)家,n支筷子,他們的生活方式只是交替地進(jìn)行思考和進(jìn)餐,饑餓時(shí)便試圖取其左、右最靠近他的筷子,只有在他拿到兩支筷子時(shí)才能進(jìn)餐,進(jìn)餐完畢,放下筷子又繼續(xù)思考。


根據(jù)描述,實(shí)現(xiàn)代碼如下:

import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit;public class Question17 {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 j = 0; j < sum; j++) {exec.execute(new Philosopher(chopsticks[j], chopsticks[(j + 1) % sum], j));}} }// 筷子 class Chopstick {// 筷子位置??private int id;// 狀態(tài)private boolean isUsed = false;public Chopstick(int id) {this.id = id;}// 拿取public synchronized void take() throws InterruptedException {while (isUsed) {wait();}System.err.println(this + " 被使用");isUsed = true;}// 放下public synchronized void drop() {isUsed = false;System.err.println(this + " 被放下");notifyAll();}@Overridepublic String toString() {return "筷子[" + id + "]";} }// 哲學(xué)家 class Philosopher implements Runnable {private Chopstick left;private Chopstick right;private int id;private Random rand = new Random();public Philosopher(Chopstick left, Chopstick right, int id) {this.left = left;this.right = right;this.id = id;}@Overridepublic void run() {while (!Thread.interrupted()) {try {think();System.out.println(this + " 想吃飯!");eat();} catch (InterruptedException e) {System.err.println(this + " InterruptedException");}}}// 思考private void think() throws InterruptedException {System.out.println(this + " 思考...");TimeUnit.MILLISECONDS.sleep(rand.nextInt(1) * 100);}// 吃飯private void eat() throws InterruptedException {left.take();right.take();System.out.println(this + " 正在吃飯...");TimeUnit.MILLISECONDS.sleep(rand.nextInt(2) * 100);left.drop();right.drop();}@Overridepublic String toString() {return "哲學(xué)家[" + id + "]";} }


通過運(yùn)行結(jié)果,我們可以發(fā)現(xiàn),到最后,沒有一個(gè)哲學(xué)家能過同時(shí)獲取兩只筷子吃飯。


二、為什么會(huì)產(chǎn)生死鎖

死鎖問題被認(rèn)為是線程/進(jìn)程間切換消耗系統(tǒng)性能的一種極端情況。在死鎖時(shí),線程/進(jìn)程間相互等待資源,而又不釋放自身的資源,導(dǎo)致無窮無盡的等待,其結(jié)果是任務(wù)永遠(yuǎn)無法執(zhí)行完成。哲學(xué)家問題便是線程資源競爭導(dǎo)致的死鎖現(xiàn)象,在程序運(yùn)行一段時(shí)間后,程序所處的狀態(tài)是n位哲學(xué)家(n個(gè)線程)都各自獲取了一只筷子的狀態(tài),此時(shí)所有哲學(xué)家都想獲取第二只筷子去吃飯,但是共享資源n只筷子已經(jīng)都被n位哲學(xué)家握在手里了,彼此想要的筷子都在其他哲學(xué)家手中,又沒有機(jī)制能讓任何哲學(xué)家放棄握在手中的筷子,從而照成了所有哲學(xué)家(所有線程)都在等待其他人手中資源的死鎖問題。


產(chǎn)生死鎖的四個(gè)必要條件:?

  • 互斥條件:一個(gè)資源每次只能被一個(gè)線程/進(jìn)程使用。
  • 請(qǐng)求與保持條件:一個(gè)線程/進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放。?
  • 不剝奪條件:線程/進(jìn)程已獲得的資源,在未使用完之前,不能強(qiáng)行剝奪。
  • 循環(huán)等待條件:若干線程/進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
  • ?

    三、死鎖的解除與預(yù)防

    一般解決死鎖的途徑分為死鎖的預(yù)防,避免,檢測與恢復(fù)這三種。

    死鎖的預(yù)防是要求線程/進(jìn)程申請(qǐng)資源時(shí)遵循某種協(xié)議,從而打破產(chǎn)生死鎖的四個(gè)必要條件中的一個(gè)或幾個(gè),保證系統(tǒng)不會(huì)進(jìn)入死鎖狀態(tài)。

    死鎖的避免不限制線程/進(jìn)程有關(guān)申請(qǐng)資源的命令,而是對(duì)線程/進(jìn)程所發(fā)出的每一個(gè)申請(qǐng)資源命令加以動(dòng)態(tài)地檢查,并根據(jù)檢查結(jié)果決定是否進(jìn)行資源分配。

    死鎖檢測與恢復(fù)是指系統(tǒng)設(shè)有專門的機(jī)構(gòu),當(dāng)死鎖發(fā)生時(shí),該機(jī)構(gòu)能夠檢測到死鎖發(fā)生的位置和原因,并能通過外力破壞死鎖發(fā)生的必要條件,從而使得并發(fā)進(jìn)程從死鎖狀態(tài)中恢復(fù)出來。

    對(duì)于java程序來說,產(chǎn)生死鎖時(shí),我們可以用jvisualvm/jstack來分析程序產(chǎn)生的死鎖原因,根治死鎖問題。




    總結(jié)

    以上是生活随笔為你收集整理的哲学家就餐与死锁问题,死锁产生的条件以及解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。