哲學家就餐問題-Java語言實現死鎖避免


哲學家就餐問題-Java語言實現死鎖避免

我死鎖預防是至少破壞死鎖產生的四個必要條件之一,帶來的問題就是系統資源利用率低且不符合開發習慣,而死鎖避免不是事先釆取某種限制措施破壞死鎖的必要條件,只是注意避免死鎖的最終發生。

哲學家就餐問題

5 個沉默寡言的哲學家圍坐在圓桌前,每人面前一盤意面。叉子放在哲學家之間的桌面上。(5 個哲學家,5 根筷子)

所有的哲學家都只會在思考和進餐兩種行為間交替。哲學家只有同時拿到左邊和右邊的筷子才能吃到面,而同一根筷子在同一時間只能被一個哲學家使用。每個哲學家吃完面后都需要把筷子放回桌面以供其他哲學家吃面。只要條件允許,哲學家可以拿起左邊或者右邊的筷子,但在沒有同時拿到左右筷子時不能進食。

產生死鎖的四個必要條件:

(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不可剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 環路等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
只要系統發生了死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。

解除死鎖:從死鎖進程處剝奪資源;終止部分或全部進程

Java語言實現死鎖避免Demo

加鎖前檢查需要的資源是否足夠,只有哲學家兩邊的筷子都沒人用時同時拿起

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class DiningPhilosophers {
    //5根筷子的狀態,0代表未使用,1代表已使用
    public static int[] chopsticks = new int[5];
    public static ReentrantLock lock = new ReentrantLock();
    public static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new Philosophers(i)).start();
        }
    }

    static class Philosophers implements Runnable {
        public int No;

        public Philosophers(int no) {
            No = no;
        }

        private void eat() {
            System.out.println("哲學家 " + No + " is eating");
            try {
                Thread.currentThread().sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void think() {
            System.out.println("哲學家 " + No + " is thinking");
            try {
                Thread.currentThread().sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void takeChopsticks() {
            lock.lock();
            //如果右邊的筷子和左邊的筷子都沒有被使用
            if (chopsticks[No] == 0 && chopsticks[(No + 4) % 5] == 0) {
                chopsticks[No] = 1;
                chopsticks[(No + 4) % 5] = 1;
            } else {
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            lock.unlock();
        }

        private void putdownChopsticks() {
            lock.lock();
            chopsticks[No] = 0;
            chopsticks[(No + 4) % 5] = 0;
            condition.signalAll();
            lock.unlock();
        }

        @Override
        public void run() {
            while (true) {
                this.think();
                this.takeChopsticks();
                this.eat();
                this.putdownChopsticks();
            }
        }
    }
}
    /*      哲學家 0 is thinking
            哲學家 4 is thinking
            哲學家 1 is thinking
            哲學家 3 is thinking
            哲學家 2 is thinking
            哲學家 0 is eating
            哲學家 2 is eating
            哲學家 2 is thinking
            哲學家 0 is thinking
            哲學家 1 is eating
            哲學家 3 is eating
            哲學家 4 is eating
            哲學家 0 is eating
            哲學家 3 is thinking
            哲學家 2 is eating
            哲學家 1 is thinking
            ………………………………		*/

給鎖添加時限:先拿起右邊的筷子,再嘗試拿左邊的筷子,如果一段時間后依然沒有拿到左邊的筷子,則放下右邊的筷子

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class DiningPhilosophers2 {

    public static ReentrantLock[] chopsticks = new ReentrantLock[5];
    public static Condition[] conditions = new Condition[5];

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            chopsticks[i] = new ReentrantLock();
            conditions[i] = chopsticks[i].newCondition();
        }
        for (int i = 0; i < 5; i++) {
            new Thread(new Philosophers(i)).start();
        }
    }

    static class Philosophers implements Runnable {

        public int No;

        public Philosophers(int no) {
            No = no;
        }

        private void eat() {
            System.out.println("哲學家 " + No + " is eating");
            try {
                Thread.currentThread().sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void think() {
            System.out.println("哲學家 " + No + " is thinking");
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void takeChopsticks() {
            //是否獲取了兩個筷子
            boolean acquire = false;
            while (true) {
                if (chopsticks[No].tryLock()) {
                    while (true) {
                        if (!chopsticks[(No + 4) % 5].tryLock()) {
                            chopsticks[No].unlock();
                            try {
                                Thread.currentThread().sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        } else {
                            acquire = true;
                        }
                        break;
                    }
                    if (acquire) {
                        chopsticks[(No + 4) % 5].unlock();
                        chopsticks[No].unlock();
                        break;
                    }

                }
            }
        }

        private void putdownChopsticks() {
            chopsticks[(No + 4) % 5].lock();
            chopsticks[No].lock();
            conditions[No].signalAll();
            conditions[(No + 4) % 5].signalAll();
            chopsticks[(No + 4) % 5].unlock();
            chopsticks[No].unlock();
        }

        @Override
        public void run() {
            while (true) {
                this.think();
                this.takeChopsticks();
                this.eat();
                this.putdownChopsticks();
            }
        }
    }
}
/*      哲學家 0 is thinking
        哲學家 2 is thinking
        哲學家 4 is thinking
        哲學家 1 is thinking
        哲學家 3 is thinking
        哲學家 0 is eating
        哲學家 2 is eating
        哲學家 1 is eating
        哲學家 3 is eating
        哲學家 4 is eating
        哲學家 0 is thinking
        哲學家 1 is thinking
        哲學家 2 is thinking
        哲學家 0 is eating
        哲學家 3 is thinking
        哲學家 4 is thinking
        哲學家 2 is eating
        哲學家 1 is eating
        哲學家 3 is eating
        哲學家 0 is thinking
        哲學家 2 is thinking
        哲學家 1 is thinking
        哲學家 4 is eating
        哲學家 0 is eating
        哲學家 3 is thinking
        哲學家 1 is eating
        哲學家 4 is thinking
        哲學家 2 is eating
        哲學家 3 is eating*/





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM