gpt4 book ai didi

java - notifyAll() 不通知所有线程

转载 作者:行者123 更新时间:2023-12-02 12:32:35 26 4
gpt4 key购买 nike

这是我的代码,每次运行代码时输出都会有所不同。有时,所有三个读者都会收到通知,输出为:

等待计算...

等待计算...

等待计算...

完成

总计:4950Thread-1

总计:4950Thread-2

总计:4950Thread-0

有时只有两名或一名读者会收到通知。有什么问题吗?

class Reader extends Thread {
Calculator c;

public Reader(Calculator calc) {
c = calc;
}

public void run() {
synchronized (c) {
try {
System.out.println("Waiting for calculation...");
c.wait();
} catch (InterruptedException e) {
}
System.out.println("Total is: " + c.total +Thread.currentThread().getName());
}
}

public static void main(String[] args) {
Calculator calculator = new Calculator();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Thread(calculator).start();
}
}

class Calculator implements Runnable {
int total;

public void run() {
synchronized (this) {
for (int i = 0; i < 100; i++) {
total += i;
}
System.out.println("Finished");
notifyAll();
}
}
}

根据元帖子,这个问题被认为是重复的,但两个被欺骗的“重复”根本不适用。 How to use wait and notify in Java?提醒用户,如果您确实想等待同一个对象,则必须对该对象进行同步。但这个解决方案已经在这样做了。 Java: notify() vs. notifyAll() all over again提醒用户 notifynotifyAll 之间的区别,这甚至离问题更远。

最佳答案

我能够重现该问题 - 基本上,如果您的计算机速度太快,或者调度不当,计算器可能会在读者有机会同步和等待之前完成。

c:\files\j>java Reader
Waiting for calculation...
Waiting for calculation...
Finished
Waiting for calculation...
Total is: 4950Thread-2
Total is: 4950Thread-0

为防止出现这种情况,您应该在执行计算之前验证所有读取器是否已准备好。

c:\files\j>java 阅读器等待计算...正在等待读者...目前 1等待计算...等待计算...完成的总计:4950Thread-1总计:4950Thread-2总计:4950Thread-0

这是我的代码

import java.util.concurrent.atomic.AtomicInteger; // corsiKa added import
class Reader extends Thread {

static class Calculator implements Runnable {
int total;
AtomicInteger readers = new AtomicInteger(0); // corsiKa added atomicinteger

public void run() {
// corsiKa added while
while(readers.get() < 3) {
System.out.println("Waiting for readers... currently " + readers.get());
try { Thread.sleep(100); } catch(InterruptedException e) { }
}
synchronized (this) {
for (int i = 0; i < 100; i++) {
total += i;
}
System.out.println("Finished");
notifyAll();
}
}
}

Calculator c;

public Reader(Calculator calc) {
c = calc;
}

public void run() {
synchronized (c) {
try {
c.readers.incrementAndGet(); // corsiKa added increment
System.out.println("Waiting for calculation...");
c.wait();
} catch (InterruptedException e) {
}
System.out.println("Total is: " + c.total +Thread.currentThread().getName());
}
}

public static void main(String[] args) {
Calculator calculator = new Calculator();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Thread(calculator).start();
}
}

关于java - notifyAll() 不通知所有线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45226466/

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