Java线程: wait and notify methods

标签 java multithreading wait notify

我有一个线程调用 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/

相关文章:

java - 独立运行 Camel 并让它继续运行

c - MPI_Init() VS MPI_Init_thread()

multithreading - 如何在UML中表示非顺序代码?

python - 等到元素不出现 - Selenium

java - 启动Firefox并等待其关闭

java - 有没有更好的方法让我的计算机对手生成 (3 > 随机长度 <= 7) 的单词?

java - Drools Salience 的最大值和最小值是多少

JavaFx 和套接字监听器

java - 多线程jsp?

javascript - 等待所有 jQuery ajax 调用完成(完成或拒绝)