【发布时间】:2014-01-26 16:14:46
【问题描述】:
我在试图弄清楚下面的代码如何工作时遇到了一些问题。在输出中,我得到所有线程都说它们处于休眠状态,然后 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.");
}
}
【问题讨论】:
-
我想我至少应该投赞成票,我试图告诉你主线程是执行的线程.. =)
-
一般原则:如果您有一个
wait没有围绕它的 while 循环来检查条件,那么您(几乎)肯定有一个等待发生的错误。 -
谢谢!我需要 dem 点。
-
您将
wakeUp和wakeupAll方法添加到 Thread 对象的方法导致您感到困惑。您不会告诉特定线程唤醒——而是,lock.notify()告诉 一个 等待线程唤醒(哪个线程取决于 JVM)。但是您的代码编写方式,似乎就像您打算告诉特定的SleepingThreads实例唤醒。
标签: java multithreading