gpt4 book ai didi

Java 线程 : wait and notify methods

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:42:46 24 4
gpt4 key购买 nike

我有一个调用 wait 方法的线程,它只能在从其他类调用 notify 方法时被唤醒:

 class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();

synchronized(b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}

class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total += i;
}
notify();
}
}
}

在上面的代码中,如果 main 中的 synchronized block ,如果 ThreadA 没有先执行,而是执行另一个同步块(synchronized block)完成到完成,然后 ThreadA 执行它的 synchronized block 并调用 wait,将要发生什么以及如何再次通知它?

最佳答案

如果 ThreadBThreadA 之前通过它的 synchronized block ,那么 ThreadA 将无限期地阻塞调用等待。不会以某种方式通知它另一个线程已经完成。

问题是您正尝试以并非设计用于使用的方式使用 waitnotify。通常,waitnotify 用于让一个线程等待某个条件为真,然后让另一个线程发出条件可能已为真的信号。例如,它们通常按如下方式使用:

/* Producer */
synchronized (obj) {
/* Make resource available. */
obj.notify();
}

/* Consumer */
synchronized (obj) {
while (/* resource not available */)
obj.wait();

/* Consume the resource. */
}

上述代码之所以有效,是因为哪个线程先运行并不重要。如果生产者线程创建了一个资源并且没有人在objwait,那么当消费者运行时它会进入while循环,注意资源已生成,然后跳过对 wait 的调用。然后它可以消耗资源。另一方面,如果消费者先运行,它会在 while 循环中注意到资源尚不可用,并将等待其他对象通知它.然后另一个线程可以运行、生成资源,并通知 资源可用的使用者线程。一旦原始线程被唤醒,它会注意到循环的条件不再为真,并将消耗资源。

更一般地说,Java 建议您始终在循环中调用 wait,因为虚假通知,其中线程可以从对 wait< 的调用中唤醒 没有任何通知。使用上述模式可以防止这种情况。

在您的特定实例中,如果您想确保 ThreadBThreadA 执行之前完成运行,您可能需要使用 Thread.join(),它显式地阻塞调用线程,直到其他线程执行。更一般地说,您可能想要研究 Java 提供的其他一些同步原语,因为它们通常比 waitnotify 更容易使用。

关于Java 线程 : wait and notify methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5121173/

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