我在尝试弄清楚下面的代码如何工作时遇到一些问题。在输出中,我得到所有线程都说它们处于 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.");
}
}
最佳答案
有两件事:
在
threads[5]
实例上调用wakeUp()
和wakeUpAll()
方法,但不在其执行线程上调用。它们在主线程上被调用。因此,即使threads[5]
thread 处于 sleep 状态,您也可以调用它。main
必须 hibernate 200 毫秒的原因是,如果不 hibernate ,则当您调用wakeUpAll()
时,某些线程(那些没有说“但现在我醒了”的线程)尚未启动(即,它们尚未执行run
方法,或者尚未到达lock.wait()
)。因此notifyAll()
发生在调用lock.wait()
之前,并且在等待后永远不会收到通知。
关于java - 这些 sleep 线程如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21365894/