gpt4 book ai didi

java - notify() 表现得像 notifyAll()

转载 作者:搜寻专家 更新时间:2023-10-30 21:18:48 26 4
gpt4 key购买 nike

<分区>

我有一个计算器线程计算从 1 到 50 的数字总和,还有多个读取器线程在计算器线程准备好后显示结果。我可以选择调用 notify() 和 notifyAll() 来通知 Reader 线程计算结果已准备好显示。在 Calculator 类的 LINE B 中,如果我调用 notifyAll() 方法,结果将按预期打印 4 次。但是当我用 notify() 替换 LINE B 时,我仍然看到打印了 4 次的结果,这似乎不正确。据我了解,notify() 只会唤醒正在等待的线程之一,而不是全部。为什么当我调用 notify 时所有线程都被唤醒并打印结果?

public class ThreadWaitNotify {

public static void main(String[] args) {
Calculator c = new Calculator();
Reader r = new Reader(c);
Reader r2 = new Reader(c);
Reader r3 = new Reader(c);
Reader r4 = new Reader(c);

r.start();
r2.start();
r3.start();
r4.start();
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}

c.start();
}

}

读者类:

class Reader extends Thread {

Calculator c;

public Reader(Calculator c) {
this.c = c;
}

@Override
public void run() {
synchronized (c) {
try {
System.out.println(Thread.currentThread().getName() + " Waiting for calculations: ");
c.wait(); // LINE A
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " Total: " + c.getSum());
}
}
}

计算器类:

class Calculator extends Thread {

private int sum = 0;

@Override
public void run() {
synchronized (this) {
for (int i = 1; i <= 50; i++) {
sum += i;
}
notify(); // LINE B
}
}

public int getSum() {
return sum;
}
}

输出:

Thread-1 Waiting for calculations: 
Thread-4 Waiting for calculations:
Thread-3 Waiting for calculations:
Thread-2 Waiting for calculations:
Thread-1 Total: 1275
Thread-2 Total: 1275
Thread-3 Total: 1275
Thread-4 Total: 1275

======================

更新:使用对象作为监视器/锁而不是 Thread 实例会产生正确的行为。

更新的 ThreadWaitNotify 类:

public class ThreadWaitNotify {

public static void main(String[] args) {
Object monitor = new Object();
Calculator c = new Calculator(monitor);
Reader r = new Reader(c, monitor);
Reader r2 = new Reader(c, monitor);
Reader r3 = new Reader(c, monitor);
Reader r4 = new Reader(c, monitor);

r.start();
r2.start();
r3.start();
r4.start();
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}

c.start();
}

}

更新的读者类:

class Reader extends Thread {

Calculator c;
Object monitor;

public Reader(Calculator c, Object monitor) {
this.c = c;
this.monitor = monitor;
}

@Override
public void run() {
synchronized (monitor) {
try {
System.out.println(Thread.currentThread().getName() + " Waiting for calculations: ");
monitor.wait(); // LINE A
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " Total: " + c.getSum());
}
}
}

更新的计算器类:

class Calculator extends Thread {

private int sum = 0;
Object monitor;

public Calculator(Object monitor) {
this.monitor = monitor;
}

@Override
public void run() {
synchronized (monitor) {
for (int i = 1; i <= 50; i++) {
sum += i;
}
monitor.notify(); // LINE B
}
}

public int getSum() {
return sum;
}
}

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