这些睡眠线程如何工作?

时间:2014-01-26 16:14:47

标签: java multithreading

我在尝试弄清楚下面的代码是如何工作时遇到了一些问题。在输出中,我得到所有线程说它们都很困,然后Thread-1或Thread-0唤醒并且程序冻结。

我理解Thread-1或Thread-0唤醒是因为threads[5]调用了notify()函数,所以等待集中的第一个线程恢复了生命。但是......如果threads[5]中的帖子因为wait()被调用而被阻止,它怎么还能调用wakeUp()函数?

如果以某种方式它可以调用方法,为什么wakeUpAll()函数不起作用?如果我睡觉主线程它为什么会起作用?

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.");
    }
}

2 个答案:

答案 0 :(得分:1)

两件事:

  1. wakeUp() 实例上调用了wakeUpAll()threads[5]方法,但未执行线程 。它们是在线程上调用的。因此,即使threads[5] 线程处于睡眠状态,您也可以调用它。

  2. main必须睡眠200ms的原因是因为如果没有,一些线程(那些不说“但现在我醒来”的线程还没有开始,当你打电话给wakeUpAll()时(即他们还没有执行run方法,或者他们还没有到lock.wait())。就这样{{1} } 之前他们会调用notifyAll(),等待后就不会收到通知。

答案 1 :(得分:0)

线程5没有调用.wakeUp(),主线程正在调用.wakeUp()