java - Java 中 wait() 和 notifyAll() 的行为?

标签 java multithreading concurrency java-threads

请注意,这不是实际情况。我根据我的实际实现创建了一个示例场景,以便于查看。我也已经得到了预期的输出。但是,我需要澄清一些关于 wait() 的概念。和 notifyAll() Java中的方法。 (在这里,这两个线程都将在主线程中立即启动 run 方法。)所以据我所知,由于线程 B 正在 hibernate ,因为您可以在初始阶段看到 reamingCount 是 400。
所以线程 B 将调用它的 MUTEX.wait()并继续 hibernate ,直到某个其他线程调用 notify()notifyAll() ,则在剩余计数减为 0 后,线程 A 将调用 MUTEX.notifyAll();唤醒线程 B 和 MUTEX.wait()释放其已授予的锁,并进入休眠状态,直到线程 B 通知它。
当我调用 MUTEX.notifyAll()通过线程 A,线程 B 不会在线程 A 调用 MUTEX.wait() 之前唤醒并继续其任务?
我的意思是,你可以看到线程 A 何时调用 MUTEX.notifyAll() ,线程 B 将唤醒并再次检查 while 循环中的条件是真还是假。因此,由于剩余计数等于 0,线程 B 将退出 while 循环并在线程 A 调用 wait() 之前继续其任务。 .这种情况会不会违反 wait() 的原则? ?据我所知,线程 B 只能在线程 A 调用 wait() 时继续执行。 .

public class A implements Runnable{

    public static volatile remainingCount =400;
    private final Object MUTEX;//Both class A and B holds the same object mutex

    private void methodA(){

         synchronized(MUTEX){
             
              while(remainingCount == 0){

                     MUTEX.notifyAll();
                     MUTEX.wait();
              }

              //Perform it's usual task.In here remaining count will decrement during the process.
              

        }
      @Override
      public void run() {

        while(true){
          methodA();
        }
     }
   }
}
public class B implements Runnable{

         private final Object MUTEX;//Both class A and B holds the same object mutex

         private void methodB(){
              synchronized(MUTEX){

                   while (A.remainingCount != 0) {
                        try {
                    
                               MUTEX.wait();
                     
                        } catch (InterruptedException ex) {
                               Logger.getLogger(InkServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
                        }
                   }
                      //incrementing the A.remainingCount 

                      MUTEX.notifyAll();
 
            }
            
           @Override
           public void run() {

                  while(true){
                     methodB();

                   }
             }
}

最佳答案

当持有锁的线程调用wait()在锁定的对象上,线程被添加到对象的等待集中并释放锁。
当持有锁的线程调用notify() ,并且等待集合不为空,则选择并移除等待集中的线程。同样,调用notifyAll()从等待集中删除所有线程。
注意:线程也可以通过调用 thread.interrupt() 从等待集中移除。 .
当一个线程从等待集中移除并开始运行时,第一步是重新获取锁。这发生在从 wait() 返回之前。 .
直到调用 notify() 的线程才会发生这种情况。或 notifyAll()通过调用 wait() 释放锁或退出同步块(synchronized block)。
因此,虽然您的线程 B 已启用运行,但它实际上不会从 wait() 返回直到线程 A 通过调用 MUTEX.wait() 释放锁.同样,当 B 调用 MUTEX.notifyAll() 时,线程 A 可以运行。 ,但不从 wait() 返回直到线程 B 退出 synchronized(MUTEX)堵塞。

关于java - Java 中 wait() 和 notifyAll() 的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65651597/

相关文章:

java - 多线程通信(java)

multithreading - Node.js C++ 插件 : Multiple callbacks from different thread

scala - 并行 map 操作?

java - 将 ArrayList <String> 转换为 ArrayList<SelectItem>

java - Eclipse CDT中获取调用层级

java - LDAP 搜索两个组

Python 作用域和线程问题

go - fatal error - 所有 Goroutines 都在 sleep !僵局

go - 在go中定期运行一个函数

java - 当没有更多行可读取时扫描仪停止