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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java中哲学家就餐死锁_哲学家就餐问题与死锁总结

發布時間:2025/3/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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){}

}

}

總結

以上是生活随笔為你收集整理的java中哲学家就餐死锁_哲学家就餐问题与死锁总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。