Java 这些睡眠线程是如何工作的?
我在试图弄清楚下面的代码是如何工作的时遇到了一些问题。在输出中,我得到所有线程都表示它们处于休眠状态,然后线程1或线程0被唤醒,程序冻结 我知道Thread-1或Thread-0被唤醒是因为Java 这些睡眠线程是如何工作的?,java,multithreading,Java,Multithreading,我在试图弄清楚下面的代码是如何工作的时遇到了一些问题。在输出中,我得到所有线程都表示它们处于休眠状态,然后线程1或线程0被唤醒,程序冻结 我知道Thread-1或Thread-0被唤醒是因为threads[5]调用了notify()函数,所以等待集中的第一个线程恢复了生命。但是如果threads[5]中的线程因为调用了wait()而被阻塞,它怎么还能调用wakeUp()函数呢 如果它可以调用方法,为什么wakeUpAll()函数不起作用?如果我在主线程上睡觉,为什么它会起作用 public cl
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.");
}
}
公共类SleepingThreads扩展线程
{
对象锁;
公共睡眠线程(对象l){lock=l;}
公开募捐
{
System.out.println(this.getName()+“说:我困了…”);
已同步(锁定)
{
尝试{lock.wait();}catch(InterruptedException e){}
System.out.println(this.getName()+“说:但是现在我醒了…”);
}
}
public void wakeUp(){synchronized(lock){lock.notify();}}
public void wakeUpAll(){synchronized(lock){lock.notifyAll();}}
公共静态void main(字符串[]args)引发InterruptedException
{
对象锁=新对象();
SleepingThreads[]threads=新的SleepingThreads[10];
对于(int i=0;i线程5没有调用.wakeUp(),主线程正在调用.wakeUp()两件事:
wakeUp()
和wakeUpAll()
方法正在threads[5]
实例上调用,但不是在其执行线程上调用。它们正在主线程上调用。因此,即使threads[5]
线程处于休眠状态,也可以调用它
main
必须睡眠200ms的原因是,如果没有睡眠,一些线程(当您调用wakeUpAll()
时,没有说“但是现在我醒了”的线程还没有启动(即,要么它们还没有执行run
方法,要么它们还没有锁定wait()
)。因此,notifyAll()
在调用lock.wait()
之前发生,并且在等待之后,它们永远不会收到通知
如果它们都死了,run()
方法怎么能结束呢?因为它是这样的:所有线程都说它们醒了。无论如何,这个答案并不能解释我观察到的行为。为什么主线程成功地调用了wakeUp()
,但没有调用wakeUpAll()
?看到我的答案,main成功地调用了wakeUpAll(),并且没有调用notifyAll()在锁上,但这发生在某些线程等待锁之前。因此,那些在调用wakeUpAll()之后等待的线程永远不会看到notifyAll()。好的,所以只有少数线程,说他们醒来是因为他们在进入等待集之前收到通知?是的,那些说“但是现在我醒来了”的线程在wakeUpAll之前等待()被调用。那些没有说“但是现在我醒了”的线程在wakeUpAll()被调用后等待。线程执行顺序并不总是可预测的。我想我至少应该获得一个向上投票,我正试图告诉您,主线程是执行的线程….=)一般原则:如果你有一个wait
,没有一个while循环来检查条件,你(几乎)保证有一个bug正在等待发生。谢谢!我需要dem点。您向Thread对象添加wakeUp
和wakeupAll
方法的做法会让您感到困惑。您不会告诉特定的线程要唤醒,而是,lock.notify()
告诉一个等待唤醒的线程(JVM正在唤醒哪个线程).但从编写代码的方式来看,您似乎打算让特定的SleepingThreads
实例醒来。