我有一个简单的程序,但我发现它非常困惑。代码片段如下:
class Processor{
public void produce() Throws InterruptedException{
synchronized(this){
System.out.println("Producer Running...");
wait();
System.out.println("Resumed");
}
}
public void consume() Throws InterruptedException{
synchronized(this){
Thread.Sleep(2000);
System.out.println("Consumer Running... Press return key to return");
scan.nextLine();
notify();
Thread.sleep(5000);
}
}
现在我的问题是,当我们在“produce”方法中调用 wait() 时,执行会立即转移到“consume”方法。 (生产和消费在不同的线程中执行)。但是当 notify();在“consume”方法中被调用,执行不会立即转移。它等待 Thread.sleep(5000) 完成。为什么会这样?
最佳答案
嗯,原因很简单。
当线程在某个对象上调用 wait()
时,它会进入等待状态并停止执行(它会从调度中移除)。等待线程释放它占用的所有监视器(并且需要在唤醒后重新获得它们)
当一个线程在某个对象上调用 notify()
时,它会唤醒另一个等待它的线程,但它自己不会进入等待状态,所以它会继续运行。
在您的生产者线程调用通知后,它会继续运行并执行五秒钟的 sleep 。当一个线程 hibernate 时,它会保留它所占用的所有监视器(你在一个同步(this) block 中,因此你有一个“this”对象的监视器)。调度程序无法运行刚刚通知的消费者线程,因为它需要在恢复之前重新获取监视器,并且在您的生产者线程停止 hibernate 并退出同步块(synchronized block)之前,它不会被释放
关于java - 混淆等待、通知和 hibernate ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23902486/