Java线程可以通过以下任一方式保存:
上述两种场景在Java线程状态方面有什么区别?
考虑以下简单代码:
synchronized(object) {
object.wait();
System.out.println("Completed.");
}
如果两个线程(比如ThreadA和ThreadB)全部都保存在wait()方法中。当另一个线程调用notifyAll()时,ThreadA将从等待中恢复并获取对象的锁定并继续,例如。 ThreadB也将恢复但无法获取对象的锁定并保持直到ThreadA退出synchronized块。然后ThreadB获得锁定并继续。
结果将是两个"已完成"印刷。
在这个例子中,ThreadB必须有一段时间从"由wait()"因为它无法锁定对象而被关押#34;。
我想知道它在Java内部是如何工作的。请帮忙。
答案 0 :(得分:2)
查看Thread.State
,更具体地说是WAITING
和BLOCKED
州。
如果您对内部实施感兴趣,可以使用LockSupport.park()
和LockSupport.unpark(Thread)
实现这两项目标,而且实际上它们是如何在大多数地方实施的。
P.S。如果您感兴趣,以下是Windows (line 4946)和Linux (line 5808)的OpenJDK park()
实现,这里是wait()/notify()/notifyAll()
实现(第1457行)。他们的评论非常好,只要给它一些时间,如果一眼看上去太复杂了。
答案 1 :(得分:2)
处于object.wait()
状态和等待object
监视器上的锁定之间的区别是object.wait()
状态的线程释放了它所拥有的object
的所有监视器,它将与系统中的所有线程竞争再次重新获取监视器。这使得wait()
成为一种特殊的状态。
因此,在A
和B
(主题A和主题B)处于等待状态的情况下,他们没有同步监视器object
,它们已被暂停执行,直到其他线程调用object.notify()
或object.notifyAll()
。当notifyAll()
被调用时,JVM唤醒A
状态中的所有线程(在这种情况下为B
和object.wait()
),他们竞争获取当前synchronized
的监视器1}}阻止。如果调用notify()
,则JVM随机选择A或B.
这里需要注意的是,JVM没有通知任何特定的线程,这就是为什么每个等待的线程都必须在while(notify_condition_for_me)
循环中等待,以验证等待条件是否有如果不是,它必须再次进入object.wait()
状态。
所以正确的代码应该是
synchronized(object) {
while(myResourceArrived) {//like URL data, JDBC data or something
object.wait();
}
System.out.println("Completed.");
}
当A
和B
处于object.wait()
状态时,他们已经释放了之前为object
保留的所有监视器,因此在synchronized
之外等待的任何其他线程{1}}阻止将立即通过获取object
的已发布监视器来进入该区块。