java - 为什么在这种简单情况下 notifyAll() 不恢复其他线程?

标签 java multithreading concurrency

我是 Java 并发的新手。我有一个包含 3 个方法的简单对象,每个方法对应于 3 个不同线程运行的代码。为什么本例中的notifyAll()语句没有释放其他两个线程中的等待?

public class Main {
static class Obj {
      synchronized void t1 () {
          System.out.println("T1 ran");
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          notifyAll();
      }
     synchronized void t2 () {
         try {
             wait();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         System.out.println("T2 ran");
     }
    synchronized void t3() {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("T3 ran");
    }
}

public static void main(String[] args) {
    final Obj o = new Obj();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t1();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t2();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            o.t3();
        }
    }).start();
}}

我预计: T1跑 ~~暂停1秒~~ T2跑 T3运行

我得到: T1跑

最佳答案

Thread.sleep 不会像 wait 那样释放或放松任何锁,所以同步仍然完全有效,其他线程不会允许在 sleep 期间进入他们的方法。

如果你更换

Thread.sleep(1000);

wait(1000);

其他线程将被允许捕获相同的锁,进入方法,开始等待,示例将按您预期的方式工作。

关于java - 为什么在这种简单情况下 notifyAll() 不恢复其他线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26822156/

相关文章:

java - 如何在我的 Java 小程序中使用 paint() 方法之外的图形?

c++ - 您可以在引用该类内部函数的类中初始化线程吗?

java - 什么时候应该将方法声明为同步?

ios - 使用 NSMainQueueConcurrencyType 时是否需要在 performBlock 中读取核心数据?

c - 在没有锁的情况下在 x86 机器上读/写一个 int

java - 使用自定义参数对列表进行排序

java - 使用 HQL 从 select 中的子选择创建对象列表

java - 部署报错Unable to compile class for JSP

c# - 取消线程任务

java - 多线程如何顺序处理?