美文网首页
哲学家问题死锁

哲学家问题死锁

作者: YAOPRINCESS | 来源:发表于2020-09-15 20:18 被阅读0次
    image.png
    package com.kang.multithread;
    
    import lombok.SneakyThrows;
    
    /**
     * @author klr
     * @create 2020-09-15-19:58
     */
    
    //哲学家问题
    public class TestDeadLock {
    
        public static void main(String[] args) {
            Chopstick c1 = new Chopstick("1");
            Chopstick c2 = new Chopstick("2");
            Chopstick c3 = new Chopstick("3");
            Chopstick c4 = new Chopstick("4");
            Chopstick c5 = new Chopstick("5");
    
            new Philosopher("苏格拉底",c1,c2).start();
            new Philosopher("柏拉图",c2,c3).start();
            new Philosopher("亚里士多德",c3,c4).start();
            new Philosopher("赫拉克利特",c4,c5).start();
            new Philosopher("阿基米德",c5,c1).start();
    
    
        }
    }
    
    class Chopstick{
        private String name;
    
        public Chopstick(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    class Philosopher extends Thread {
    
        String name;
        Chopstick left;
        Chopstick right;
    
        public Philosopher(String name, Chopstick left, Chopstick right) {
            super(name);
            this.name=name;
            this.left = left;
            this.right = right;
        }
    
        @SneakyThrows
        @Override
        public void run() {
            while (true) {
                synchronized (left) {
                    synchronized (right) {
                        //获取了两个筷子后才能吃饭
                        eat();
                    }
                }
            }
        }
    
        public void eat() throws InterruptedException {
            System.out.println("eating..."+name);
            Thread.sleep(1000);
        }
    }
    

    解决方法

    1.改变拿筷子的次序
    c1,c2/c1,c5
    这样做后有的线程得到锁的机会就少了

    2.使用reentrantlock
    这样获取锁失败并不会进入阻塞队列等待,而是直接跳过

    package com.kang.multithread;
    
    import lombok.SneakyThrows;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author klr
     * @create 2020-09-15-19:58
     */
    
    //哲学家问题
    public class TestDeadLock {
    
        public static void main(String[] args) {
            Chopstick c1 = new Chopstick("1");
            Chopstick c2 = new Chopstick("2");
            Chopstick c3 = new Chopstick("3");
            Chopstick c4 = new Chopstick("4");
            Chopstick c5 = new Chopstick("5");
    
            new Philosopher("苏格拉底",c1,c2).start();
            new Philosopher("柏拉图",c2,c3).start();
            new Philosopher("亚里士多德",c3,c4).start();
            new Philosopher("赫拉克利特",c4,c5).start();
            new Philosopher("阿基米德",c5,c1).start();
    
    
        }
    }
    
    class Chopstick extends ReentrantLock {
        private String name;
    
        public Chopstick(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    class Philosopher extends Thread {
    
        String name;
        Chopstick left;
        Chopstick right;
    
        public Philosopher(String name, Chopstick left, Chopstick right) {
            super(name);
            this.name=name;
            this.left = left;
            this.right = right;
        }
    
        @SneakyThrows
        @Override
        public void run() {
            while (true) {
    //            synchronized (left) {
    //                synchronized (right) {
    //                    //获取了两个筷子后才能吃饭
    //                    eat();
    //                }
    //            }
                //尝试获取左筷子
                if (left.tryLock()) {
                    try {
                        //尝试获取右筷子
                        if (right.tryLock()) {
                            try {
                                eat();
                            }
                            finally {
                                right.unlock();
                            }
                        }
                    }
                    finally {
                        left.unlock();//释放左筷子
                    }
                }
            }
        }
    
        public void eat() throws InterruptedException {
            System.out.println("eating..."+name);
            Thread.sleep(1000);
        }
    }
    

    相关文章

      网友评论

          本文标题:哲学家问题死锁

          本文链接:https://www.haomeiwen.com/subject/umxqyktx.html