繁体   English   中英

餐饮哲学家实施中Thread.join()未能按预期工作

[英]Thread.join() is not working at expect in Dining Philosophers implementation

我已经使用Java中的Monitor(同步)实现了Dining Philosopher问题。

该计划的目标是:

  • 每个哲学家都应该遵循思考的流程,拿起筷子,吃饭,放筷子(没有种族条件)。

  • 无死锁

我认为这段代码似乎可以正常工作,但是有些不对劲,因为它一直运行着,我一直尝试对其进行调试,并且调试工具停止在这一行philosopher [i] .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);
        }
    }

MyPhilosopher类:

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");
    }
}

我已经执行了您的代码,它可以完美运行,直到执行两次或更多次。 此外,您可以减少睡眠时间,您的代码正确无误,但完美无缺,直到有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

但是,我已经检查过您是否处于以下某些特殊情况下的僵局:当所有哲学家中至少有一个可以吃而其他人正在等待。 但是我通过在函数的标题中使用sync更改了测试中的代码,同时使用了while()方法的test()方法的if条件以及在putdown()方法中,我通过notifyAll()更改了notify; 代码是这样的:

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();
    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM