java - 这些 sleep 线程如何工作?

标签 java multithreading

我在尝试弄清楚下面的代码如何工作时遇到一些问题。在输出中,我得到所有线程都说它们处于 hibernate 状态,然后 Thread-1 或 Thread-0 被唤醒并且程序卡住。

据我所知,Thread-1 或 Thread-0 被唤醒是因为 threads[5] 调用了 notify() 函数,因此等待集中的第一个线程恢复了生命。但是...如果 threads[5] 中的线程由于调用 wait() 而被阻塞,它怎么可能仍然调用 wakeUp() 函数呢?

如果它可以调用方法,为什么 wakeUpAll() 函数不起作用?为什么如果我让主线程 hibernate 它会起作用?

public class SleepingThreads extends Thread
{
    Object lock;

    public SleepingThreads(Object l) { lock=l; }

    public void run()
    {
        System.out.println(this.getName()+" said: I am sleepy...");
        synchronized(lock)
        {
            try { lock.wait(); } catch (InterruptedException e){}
            System.out.println(this.getName()+" said: but now I woke up...");
        }
    }

   public void wakeUp() { synchronized (lock) { lock.notify(); } }

   public void wakeUpAll() { synchronized (lock) { lock.notifyAll(); } }

    public static void main(String[] args) throws InterruptedException
    {
        Object lock = new Object();
        SleepingThreads[] threads = new SleepingThreads[10];

        for (int i=0; i<10;i++)
        {
            threads[i] = new SleepingThreads(lock); 
            threads[i].start();
        }

        threads[5].wakeUp();
        //currentThread().sleep(200);
        threads[5].wakeUpAll();

        System.out.println("Done.");
    }
}

最佳答案

有两件事:

  1. threads[5]实例上调用wakeUp()wakeUpAll()方法,但不在其执行线程上调用。它们在线程上被调用。因此,即使 threads[5] thread 处于 sleep 状态,您也可以调用它。

  2. main 必须 hibernate 200 毫秒的原因是,如果不 hibernate ,则当您调用 wakeUpAll() 时,某些线程(那些没有说“但现在我醒了”的线程)尚未启动(即,它们尚未执行 run 方法,或者尚未到达 lock.wait())。因此 notifyAll() 发生在调用 lock.wait() 之前,并且在等待后永远不会收到通知。

关于java - 这些 sleep 线程如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21365894/

相关文章:

java - 如何将业务逻辑和电子邮件发送功能分开?

windows - OpenSSL 和多线程

c++ - 在单独的线程上删除我的 qt 类后断言失败

java - 如何在 java 中使用循环读取 XML 子节点值

c - 特定线程内的自动/全局变量是否对其他线程可见

java - Selenium:元素未通过 LINK_TEXT 或 PARTIAL_LINK_TEXT 定位

java - Jersey REST 日期 @XmlAttribute 导致非法参数异常

c - 以多线程方式进行矩阵乘法

java - 为什么Java使用UTF-16作为内部文本表示

java - Java 命令行参数中的空格在 Amazon 云中引发错误