- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我的代码,每次运行代码时输出都会有所不同。有时,所有三个读者都会收到通知,输出为:
等待计算...
等待计算...
等待计算...
完成
总计: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提醒用户 notify
和 notifyAll
之间的区别,这甚至离问题更远。
最佳答案
我能够重现该问题 - 基本上,如果您的计算机速度太快,或者调度不当,计算器可能会在读者有机会同步和等待之前完成。
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/
我是一名优秀的程序员,十分优秀!