gpt4 book ai didi

java - 多线程我是否正确使用等待和通知

转载 作者:行者123 更新时间:2023-12-01 23:52:44 26 4
gpt4 key购买 nike

我写了一个哲学家问题的解决方案。它正在运行,我在控制台上得到了正确的输出,但是 wait() 之后的 println() 从未被打印。请告诉我为什么。我在代码中指出了。

该解决方案与http://en.wikipedia.org/wiki/Dining_philosophers_problem#Resource_hierarchy_solution类似

public class Philosopher extends Thread {
String name;
// boolean je, czeka;
int nr;
Fork left, right;

public Philosopher(String name, int nr, Fork left, Fork right) {
this.nr = nr;
this.name = name;
this.left = left;
this.right = right;
System.out.println("NR " + nr +" "+ left + " " + right);
}

public void run() {
// while(true){
try {
Fork minF = Fork.min(left, right);
Fork maxF = Fork.max(left, right);

synchronized (minF) {
if (!minF.used) {
minF.used = true;
System.out.println("P" + nr + " took fork " + minF);
} else {
minF.wait();
minF.used = true;
System.out.println("I waited and took fork " + minF); //why it is never PRINTEDDD???
}
synchronized (maxF) {
if (!maxF.used) {
maxF.used = true;
System.out.println("P" + nr + " took fork "
+ maxF);
} else {
maxF.wait();
maxF.used = true;
System.out.println("I waited and took fork "+ maxF); //why it is never PRINTEDDD??
}
System.out.println("I am eating right now" + this);
eating();
System.out.println("P" + nr
+ " I have eaten I am giving back the forks");
minF.used = false;
System.out.println("P" + nr + " NOTIFY fork" + minF);
minF.notify();
maxF.used = false;
System.out.println("P" + nr + " NOTIFY fork" + maxF);
maxF.notify();
}
}
} catch (Exception e) {
}

// }
}

public void eating() throws InterruptedException {
int time = (int) (Math.random() * 2000);

for (int i = 0; i < 5; i++) {
System.out.println("P" + nr + " " + i);
Thread.sleep(time / 5);
}
}

public String toString() {
return "Philosopher " + nr;
}

public static void startPhilosophers(Philosopher[] f) {
for (int i = f.length - 1; i >= 0; i--) {
f[i].start();
}
}

public static void main(String[] args) {
Fork[] t = Fork.getArrayOfForks();
Philosopher[] f = { new Philosopher("philosopher 1", 1, t[0], t[4]),
new Philosopher("philosopher 2", 2, t[1], t[0]),
new Philosopher("philosopher 3", 3, t[2], t[1]),
new Philosopher("philosopher 4", 4, t[3], t[2]),
new Philosopher("philosopher 5", 5, t[4], t[3]), };
startPhilosophers(f);

}

}
<小时/>
public class Fork {
boolean used;
int nr;

public Fork(boolean used, int nr) {
this.used = used;
this.nr = nr;
}

@Override
public String toString() {
return "F" + nr;
}
public static Fork min(Fork l, Fork p){
if(l.nr < p.nr)
return l;
return p;
}


public static Fork max(Fork l, Fork p){
if(l.nr > p.nr)
return l;
return p;
}
public static Fork[] getArrayOfForks() {
Fork[] t = new Fork[5];
for (int i = 0; i < t.length; i++) {
t[i] = new Fork(false, (i + 1));
}
return t;
}
}
<小时/>
EXAMPLE output
NR 1 F1 F5
NR 2 F2 F1
NR 3 F3 F2
NR 4 F4 F3
NR 5 F5 F4
P5 took fork F4
P5 took fork F5
I am eating right nowPhilosopher 5
P4 took fork F3
P5 0
P2 took fork F1
P2 took fork F2
I am eating right nowPhilosopher 2
P2 0
P5 1
P2 1
P5 2
P2 2
P5 3
P2 3
P5 4
P2 4
P5 I have eaten I am giving back the forks
P5 NOTIFY forkF4
P5 NOTIFY forkF5
P4 took fork F4
I am eating right nowPhilosopher 4
P4 0
P2 I have eaten I am giving back the forks
P2 NOTIFY forkF1
P2 NOTIFY forkF2
P3 took fork F2
P1 took fork F1
P1 took fork F5
I am eating right nowPhilosopher 1
P1 0
P1 1
P4 1
P1 2
P4 2
P1 3
P4 3
P1 4
P4 4
P1 I have eaten I am giving back the forks
P1 NOTIFY forkF1
P1 NOTIFY forkF5
P4 I have eaten I am giving back the forks
P4 NOTIFY forkF3
P4 NOTIFY forkF4
P3 took fork F3
I am eating right nowPhilosopher 3
P3 0
P3 1
P3 2
P3 3
P3 4
P3 I have eaten I am giving back the forks
P3 NOTIFY forkF2
P3 NOTIFY forkF3

最佳答案

synchronized (minF) {
if (!minF.used) { // always
minF.used = true;
}
...
minF.used = false;
minF.notify();
}

您正在同步 fork ,因此哲学家在检查 fork 是否正在使用时已经锁定了 fork 。哲学家将 fork.used 设置为 true,但在离开同步块(synchronized block)并释放锁之前将其设置回 false。

编辑:根据要求,更新了代码版本。如果您使用同步块(synchronized block)(您已经这样做了),则无需自己进行管理:

synchronized (minF) {
synchronized (maxF) {
System.out.println("I am eating right now" + this);
eating();
System.out.println("P" + nr
+ " I have eaten I am giving back the forks");
}
}

如果你想明确地写出来,我会使用java.util.concurrent类并让Fork从Semaphore扩展。 。您的代码如下所示:

fork :

public class Fork extends Semaphore {
int nr;

public Fork(int nr) {
super(1); // can be handed out to only one person at a time
this.nr = nr;
}
...

还有哲学家:

minF.acquire();
maxF.acquire();
System.out.println("I am eating right now" + this);
eating();
System.out.println("P" + nr
+ " I have eaten I am giving back the forks");
maxF.release();
minF.release();

关于java - 多线程我是否正确使用等待和通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16118845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com