代码之家  ›  专栏  ›  技术社区  ›  T. John.

线join()在Dining Physphers实现中的expect中不起作用

  •  0
  • T. John.  · 技术社区  · 6 年前

    我已经在Java中使用Monitor(Synchronized)实现了用餐哲学家问题。

    该计划的目标是:

    • 每个哲学家都应该遵循思考、拿筷子、吃饭、放筷子(无种族条件)的工作流程。

    • 无死锁

    我认为这段代码似乎工作得很好,但有些地方不太对劲,因为它永远都在运行。我试图调试它,调试工具停在这一行。t、 join();但该计划并未终止。

    请帮我确定问题或告诉我如何解决。 谢谢你的建议。

    MyMonitor类:

    class MyMonitor {
        private enum States {THINKING, HUNGRY, EATING};
        private States[] state;
    
        public MyMonitor() {
            state = new States[5];
            for(int i = 0; i < 5; i++) {
                state[i] = States.THINKING;
                System.out.println("Philosopher " + i + " is THINKING");
            }
        }
    
        private void test(int i) {
            if((state[(i+4)%5]!=States.EATING) && (state[i]==States.HUNGRY) && (state[(i+1)%5]!=States.EATING)) {
                state[i] = States.EATING;
                System.out.println("Philosopher " + i + " is EATING");
                notify();
            }
        }
    
        public synchronized void pickup(int i) {
                state[i] = States.HUNGRY;
                System.out.println("Philosopher " + i + " is HUNGRY");      
                test(i);
                if (state[i] != States.EATING) {
                    System.out.println("Philosopher " + i + " is WAITING");
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
        }
    
        public synchronized void putdown(int i) {
                state[i] = States.THINKING;
                System.out.println("Philosopher " + i + " is THINKING");
                test((i+4)%5);
                test((i+1)%5);
            }
        }
    

    我的哲学家课程:

    class MyPhilosopher implements Runnable{
        private int myID;
        private int eatNum;
        private MyMonitor monitor;
        private Thread t;
    
        public MyPhilosopher(int myID, int eatNum, MyMonitor monitor) {
            this.myID = myID;
            this.eatNum = eatNum;
            this.monitor = monitor;
            t = new Thread(this);
            t.start();
        }
    
        public void run() {
            int count = 1;
            while(count <= eatNum ){
                monitor.pickup(myID);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                monitor.putdown(myID);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
            }
        }
    
        public static void main(String[] args) {
            int eatNum = 10;
    
                System.out.println("----------------------------------------------------------------------------------------------------");
            System.out.println("xxx");
            System.out.println("xxx");
            System.out.println("xxx");
                System.out.println("----------------------------------------------------------------------------------------------------");
            System.out.println("Starting");
            System.out.println("----------------------------------------------------------------------------------------------------");
            System.out.println("");
            MyMonitor monitor = new MyMonitor();
            MyPhilosopher[] philosopher = new MyPhilosopher[5];
    
            for(int i = 0; i < 5; i++) {
                philosopher[i] = new MyPhilosopher(i, eatNum, monitor);
            }
    
    
            for(int i = 0; i < 5; i++) {
                try {
                    philosopher[i].t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
                System.out.println("----------------------------------------------------------------------------------------------------");
            System.out.println("Ended");
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Imaddin Ahmed Mohamed    6 年前

    我已经执行了您的代码,在执行两次或两次以上之前,它一直运行得很好。此外,你可以减少睡眠时间,你的代码是正确的,但很完美,直到4名飞行员等待,其中一人正在吃饭。我不喜欢它。您正在打破一个coffman条件,但我建议您使用其他实现,就像打破保持和等待条件一样。我的意思是,你可以同时使用两根筷子,也可以不使用,其他的方法也可以,甚至飞行员也可以使用右边的筷子,奇怪的飞行员也可以使用左边的筷子。祝你好运

    Philosopher 4 is THINKING
    Philosopher 0 is EATING
    Philosopher 3 is HUNGRY
    Philosopher 3 is WAITING
    Philosopher 1 is HUNGRY
    Philosopher 1 is WAITING
    Philosopher 2 is THINKING
    Philosopher 3 is EATING
    Philosopher 0 is THINKING
    Philosopher 1 is EATING
    Philosopher 4 is HUNGRY
    Philosopher 4 is WAITING
    Philosopher 3 is THINKING
    Philosopher 4 is EATING
    Philosopher 2 is HUNGRY
    Philosopher 2 is WAITING
    Philosopher 0 is HUNGRY
    Philosopher 0 is WAITING
    Philosopher 1 is THINKING
    Philosopher 2 is EATING
    Philosopher 4 is THINKING
    Philosopher 0 is EATING
    Philosopher 3 is HUNGRY
    Philosopher 3 is WAITING
    Philosopher 2 is THINKING
    Philosopher 3 is EATING
    Philosopher 1 is HUNGRY
    Philosopher 1 is WAITING
    Philosopher 0 is THINKING
    Philosopher 1 is EATING
    Philosopher 4 is HUNGRY
    Philosopher 4 is WAITING
    Philosopher 3 is THINKING
    Philosopher 4 is EATING
    Philosopher 2 is HUNGRY
    Philosopher 2 is WAITING
    Philosopher 0 is HUNGRY
    Philosopher 0 is WAITING
    Philosopher 1 is THINKING
    Philosopher 2 is EATING
    Philosopher 3 is HUNGRY
    Philosopher 3 is WAITING
    Philosopher 4 is THINKING
    Philosopher 0 is EATING
    Philosopher 2 is THINKING
    Philosopher 3 is EATING
    Philosopher 1 is HUNGRY
    Philosopher 1 is WAITING
    Philosopher 4 is HUNGRY
    Philosopher 4 is WAITING
    Philosopher 0 is THINKING
    Philosopher 1 is EATING
    Philosopher 2 is HUNGRY
    Philosopher 2 is WAITING
    Philosopher 3 is THINKING
    Philosopher 4 is EATING
    Philosopher 1 is THINKING
    Philosopher 2 is EATING
    Philosopher 0 is HUNGRY
    Philosopher 0 is WAITING
    Philosopher 4 is THINKING
    Philosopher 0 is EATING
    Philosopher 3 is HUNGRY
    Philosopher 3 is WAITING
    Philosopher 2 is THINKING
    Philosopher 3 is EATING
    Philosopher 1 is HUNGRY
    Philosopher 1 is WAITING
    Philosopher 4 is HUNGRY
    Philosopher 4 is WAITING
    Philosopher 0 is THINKING
    Philosopher 1 is EATING
    Philosopher 2 is HUNGRY
    Philosopher 2 is WAITING
    Philosopher 3 is THINKING
    Philosopher 4 is EATING
    Philosopher 0 is HUNGRY
    Philosopher 0 is WAITING
    Philosopher 1 is THINKING
    Philosopher 2 is EATING
    Philosopher 4 is THINKING
    Philosopher 0 is EATING
    Philosopher 2 is THINKING
    Philosopher 1 is HUNGRY
    Philosopher 1 is WAITING
    Philosopher 0 is THINKING
    Philosopher 1 is EATING
    Philosopher 1 is THINKING
    ----------------------------------------------------------------------------------------------------
    Ended
    

    但是,我已经检查过,您在某些特殊情况下会出现死锁,例如: 当所有的哲学家都至少有一个人能吃,而其他人却在等待的时候。但是我在测试中更改了您的代码,在函数的头中使用了synchronize,在while中使用了test()方法的if条件,在方法putdown()中,我更改了notify by notifyAll(); 代码如下:

    class MyMonitor {
    private enum States {THINKING, HUNGRY, EATING};
    private  States[] state;
    
    public MyMonitor() {
        state = new States[5];
        for(int i = 0; i < 5; i++) {
            state[i] = States.THINKING;
            System.out.println("Philosopher " + i + " is THINKING");
        }
    }
    
    private synchronized void test(int i) {
        while((state[(i+4)%5]!=States.EATING) && (state[i]==States.HUNGRY) && (state[(i+1)%5]!=States.EATING)) {
            state[i] = States.EATING;
            System.out.println("Philosopher " + i + " is EATING");
         //   notify();
        }
    }
    
    public synchronized void pickup(int i) {
            state[i] = States.HUNGRY;
            System.out.println("Philosopher " + i + " is HUNGRY");      
            test(i);
            if (state[i] != States.EATING) {
                System.out.println("Philosopher " + i + " is WAITING");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }
    
    public synchronized void putdown(int i) {
            state[i] = States.THINKING;
            System.out.println("Philosopher " + i + " is THINKING");
            //test((i+4)%5);
            //test((i+1)%5);
            notifyAll();
        }
    }
    

    我建议您使用一个或多个实现,然后再考虑您想要打破的科夫曼条件。祝你好运