gpt4 book ai didi

Java线程: wait and notify methods

转载 作者:太空宇宙 更新时间:2023-11-04 13:13:44 25 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();
}
}
}

在上面的代码中,如果synchronized阻止main ,如果ThreadA不首先执行,而是由其他同步块(synchronized block)执行并完成,然后 ThreadA执行其 synchronized阻止和调用 wait ,将会发生什么以及如何再次通知?

最佳答案

如果 ThreadBThreadA 之前完成其 synchronized block ,则 ThreadA 将在调用 wait 时无限期地阻塞。它不会以某种方式收到另一个线程已经完成的通知。

问题在于您尝试以不符合其设计用途的方式使用 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 的调用中唤醒,而不会收到任何通知。使用上述模式可以防止这种情况发生。

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

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

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