我在尝试弄清楚下面的代码是如何工作时遇到了一些问题。在输出中,我得到所有线程说它们都很困,然后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.");
}
}
答案 0 :(得分:1)
两件事:
wakeUp()
实例上调用了wakeUpAll()
和threads[5]
方法,但未执行线程 。它们是在主线程上调用的。因此,即使threads[5]
线程处于睡眠状态,您也可以调用它。
main
必须睡眠200ms的原因是因为如果没有,一些线程(那些不说“但现在我醒来”的线程还没有开始,当你打电话给wakeUpAll()
时(即他们还没有执行run
方法,或者他们还没有到lock.wait()
)。就这样{{1} } 之前他们会调用notifyAll()
,等待后就不会收到通知。
答案 1 :(得分:0)
线程5没有调用.wakeUp(),主线程正在调用.wakeUp()