利用AND信號量機制解決哲學家進餐問題


哲學家就餐問題是1965年由Dijkstra提出的一種線程同步的問題。

問題描述:一圓桌前坐着5位哲學家,兩個人中間有一只筷子,桌子中央有面條。哲學家思考問題,當餓了的時候拿起左右兩只筷子吃飯,必須拿到兩只筷子才能吃飯。上述問題會產生死鎖的情況,當5個哲學家都拿起自己右手邊的筷子,准備拿左手邊的筷子時產生死鎖現象。

解決辦法:

  1、添加一個服務生,只有當經過服務生同意之后才能拿筷子,服務生負責避免死鎖發生。

  2、每個哲學家必須確定自己左右手的筷子都可用的時候,才能同時拿起兩只筷子進餐,吃完之后同時放下兩只筷子。

  3、規定每個哲學家拿筷子時必須拿序號小的那只,這樣最后一位未拿到筷子的哲學家只剩下序號大的那只筷子,不能拿起,剩下的這只筷子就可以被其他哲學家使用,避免了死鎖。這種情況不能很好的利用資源。

參考:http://www.cnblogs.com/vettel/p/3438257.html

    package 操作系統;
    
    class Philosopher extends Thread {
    
        private String name;
        private Fork fork;
    
        public Philosopher(String name, Fork fork) {
            super();
            this.name = name;
            this.fork = fork;
        }
    
        @Override
        public void run() {
            thinking();
            fork.takeFork();
            eating();
            fork.putFork();
        }
    
        void eating() {
            System.out.println("I'm eating " + name);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        void thinking() {
            System.out.println("I'm thinking" + name);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    class Fork {
    
        boolean[] used = { false, false, false, false, false };
    
        synchronized void takeFork() {
            String threadName = Thread.currentThread().getName();
            String name = threadName.substring(threadName.length()-1, threadName.length());
            int i = Integer.parseInt(name);
            while (used[i] || used[(i + 1) % 5]) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            used[i] = true;
            used[(i + 1) % 5] = true;
    
        }
    
        synchronized void putFork() {
            String threadName = Thread.currentThread().getName();
            String name = threadName.substring(threadName.length()-1, threadName.length());
            int i = Integer.parseInt(name);
            used[i] = false;
            used[(i + 1) % 5] = false;
            notifyAll();
        }
    }
    
    public class 哲學家就餐問題 {
        public static void main(String[] args) {
            Fork fork = new Fork();
    
            new Philosopher("1", fork).start();
            new Philosopher("2", fork).start();;
            new Philosopher("3", fork).start();;
            new Philosopher("4", fork).start();;
            new Philosopher("5", fork).start();;
    
        }
    }

執行結果

I'm thinking1
I'm thinking3
I'm thinking2
I'm thinking4
I'm thinking5
I'm eating 1
I'm eating 3
I'm eating 5
I'm eating 2
I'm eating 4


免責聲明!

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



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