问题描述
我有一个著名的Philosopher问题的多线程代码示例.在这种情况下,有5位哲学家尝试进餐,但他们与旁边的下一位哲学家共享同一叉子.
I have a multithreading code example for the well known Philosopher problem. In this scenario 5 Philosophers try to eat, but they share the same fork with the next Philosopher sitting next to them.
我在理解此代码中的线程工作方式时遇到问题:
I have a problem understanding the way a Thread in this code works:
当我观察到此代码的输出时,看起来pickup
在wait
之后执行test
.但是考虑到test
明显早于wait
,这怎么可能?
When I observe the output of this code, it looks like pickup
executes test
after wait
. But how is that possible, considering test
comes clearly before wait
?
示例输出:
哲学家1正在吃东西"由test(1)
打印,被pickup(1)
调用,但这怎么可能?
"Philosoph 1 is eating" gets printed by test(1)
, which is called by pickup(1)
, but how is that possible?
课堂哲学:
class Philosoph extends Thread {
Dining_Philosophers dp;
int name;
public Philosoph(int n, Dining_Philosophers d) {
name = n;
dp = d;
}
public void run() {
while (true) {
thinking();
dp.pickup(name);
eating();
dp.putdown(name);
}
}
public static void main(String[] args) {
Dining_Philosophers dp = new Dining_Philosophers();
Philosoph p0 = new Philosoph(0, dp);
Philosoph p1 = new Philosoph(1, dp);
Philosoph p2 = new Philosoph(2, dp);
Philosoph p3 = new Philosoph(3, dp);
Philosoph p4 = new Philosoph(4, dp);
p0.start();
p1.start();
p2.start();
p3.start();
p4.start();
}
void thinking() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
void eating() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
进餐哲学家:
class Dining_Philosophers {
static int thinking = 0;
static int hungry = 1;
static int eating = 2;
int[] state = new int[5];
public Dining_Philosophers() {
for (int i = 0; i < 5; i++) {
state[i] = thinking;
}
}
public synchronized void pickup(int i) {
//The Thread executes this function, but
// when it executes the wait function und wake up after the notification by another
// thread then it executes only the test-function. But why only the it and not the
// other Code like the "System.out.println("Philosoph " + i + " is hungry");" ?
state[i] = hungry;
System.out.println("Philosoph " + i + " is hungry");
test(i);
while (state[i] != eating) {
try {
wait();
} catch (InterruptedException e) {}
}
}
public synchronized void putdown(int i) {
state[i] = thinking;
System.out.println("Philosoph " + i + " is thinking");
test((i + 4) % 5);
test((i + 1) % 5);
}
public void test(int k) {
int i;
if ((state[(k + 4) % 5] != eating) && (state[k] == hungry) && (state[(k + 1) % 5] != eating)) {
state[k] = eating;
System.out.println("Philosoph " + k + " is eating");
System.out.print("Philosophers eating: ");
for (i = 0; i < 5; i++)
if (state[i] == eating)
System.out.print(i + " ");
System.out.println(".");
notifyAll();
}
}
}
推荐答案
您会丢失test
不仅由pickup
调用,而且由putdown
调用.
You are missing that test
is not only called by pickup
, but also by putdown
.
示例中的哲学家1正在吃东西" 输出不是pickup(1)
调用的,而是putdown(0)
调用的. putdown
在哲学家之前和之后都呼叫test
给哲学家.
The "Philosoph 1 is eating" output in your example wasn't called by pickup(1)
, but by putdown(0)
. putdown
calls test
for the philosopher before and after.
表达式(i + 4) % 5
和(i + 1) % 5
可能有点令人困惑,但是(i + 4) % 5
给出了以前的哲学家:
The expressions (i + 4) % 5
and (i + 1) % 5
might be a bit confusing, but (i + 4) % 5
gives the previous philosopher:
和(i + 1) % 5
给出了下一个哲学家:
and (i + 1) % 5
gives the next philosopher:
这篇关于方法在我不期望的地方被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!