zoukankan      html  css  js  c++  java
  • 哲学家就餐问题-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*/
    
    
    
    
    

    未经作者同意请勿转载

    本文来自博客园作者:aixueforever,原文链接:https://www.cnblogs.com/aslanvon/p/15215962.html

  • 相关阅读:
    Unity设置相机正交相机和透视相机的动态切换
    获得两点之间连续坐标,向量加法、减法、乘法的运用
    替换材质
    常用的layer弹出层
    检测扇形角度
    c# 关闭socket的标准方法
    C#中Object和Json之间的转换
    Unity经验之谈-DoTween动画结束匿名委托之巨坑
    Unity透明视频播放 所需的Shader脚本
    阿里云云服务器Windows Server 2012 R2无法安装IIS等组件的解决办法
  • 原文地址:https://www.cnblogs.com/aslanvon/p/15215962.html
Copyright © 2011-2022 走看看