Thread.join() 在 Dining Philosophers 实施中无法正常工作
Thread.join() is not working at expect in Dining Philosophers implementation
我在 Java.
中使用监视器(同步)实现了 Dining Philosopher 问题
该计划的目标是:
每个哲学家都应该遵循think的工作流程,拿筷子,吃饭,放筷子(无竞争条件)。
无死锁
我认为这段代码似乎工作正常,但有些地方不对,因为它永远 运行 我试图调试它,调试工具停在 philosopher[i].t.join 这一行();但是程序没有终止。
请帮我找出问题或告诉我如何解决它。
谢谢你的建议。
我的监视器class:
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:
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 条件,但我建议你使用其他实现,比如打破保持和等待条件。我的意思是,你可以同时拿筷子或none,其他实现方式也可以,偶数的哲学家拿右边的筷子,奇数的哲学家拿左边的筷子。祝你好运!
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
但是,我已经检查过你在这样的特殊情况下是否有死锁:
当所有的哲学家至少有一个可以吃饭而其他人在等待时。但是我已经通过在函数的 header 中使用同步更改了测试中的代码,通过 while 和方法 putdown() 更改了 test() 方法的 if 条件,我通过 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();
}
}
我建议你使用一个或多个实现,然后再考虑你想打破什么 coffman 条件。祝你好运
我在 Java.
中使用监视器(同步)实现了 Dining Philosopher 问题该计划的目标是:
每个哲学家都应该遵循think的工作流程,拿筷子,吃饭,放筷子(无竞争条件)。
无死锁
我认为这段代码似乎工作正常,但有些地方不对,因为它永远 运行 我试图调试它,调试工具停在 philosopher[i].t.join 这一行();但是程序没有终止。
请帮我找出问题或告诉我如何解决它。 谢谢你的建议。
我的监视器class:
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:
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 条件,但我建议你使用其他实现,比如打破保持和等待条件。我的意思是,你可以同时拿筷子或none,其他实现方式也可以,偶数的哲学家拿右边的筷子,奇数的哲学家拿左边的筷子。祝你好运!
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
但是,我已经检查过你在这样的特殊情况下是否有死锁: 当所有的哲学家至少有一个可以吃饭而其他人在等待时。但是我已经通过在函数的 header 中使用同步更改了测试中的代码,通过 while 和方法 putdown() 更改了 test() 方法的 if 条件,我通过 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();
}
}
我建议你使用一个或多个实现,然后再考虑你想打破什么 coffman 条件。祝你好运