未能获取锁定的线程(非自旋)会发生什么情况?它进入BLOCKED状态。它是如何被再次执行的?未能获取锁的线程会发生什么情况?
Lock lck = new ReentrantLock();
lck.lock()
try
{
}
finally
{
lck.unlock();
}
未能获取锁定的线程(非自旋)会发生什么情况?它进入BLOCKED状态。它是如何被再次执行的?未能获取锁的线程会发生什么情况?
Lock lck = new ReentrantLock();
lck.lock()
try
{
}
finally
{
lck.unlock();
}
调度程序(或底层的Lock实现)负责让它再次运行。如果锁定操作被转换为一个互斥量调用一直进入内核,调度器将不会重新调度线程,直到互斥量变为可用;那么OS调度程序将重新唤醒该线程。阅读关于Context Switch的维基百科页面以及从那里的链接可能会提供更多关于所涉及的详细机制的信息。你也可以直接看ReentrantLock
的代码,尽管这最终会将你的问题归结为一些基元组合,包括AbstractedQueuedSynchronizer
,各种原子操作,也许LockSupport.park()
和unpark()
。如果您特别关心内核级别的阻塞/上下文切换,或者特别是如何在内核上实现各种Java基元(例如,j.u.c.Lock
或原始对象监视器),您可能会扩大您的问题或提出新问题。
实际上,由于这样做代价高昂,因此可以通过JVM或锁定实现来优化。例如,线程实际上可能旋转了一下,看看锁是否在实际阻塞之前被释放。
请注意,即使底层OS线程未被阻止,特别是在下面的性能白皮书中描述的自适应旋转情况下,Java线程也可能会报告状态BLOCKED。
有一些很好的资源来了解Java中的并发控制。领导万神殿的是Java Concurrency in Practice。在HotSpot 6.0 in the Java SE 6 Performance Whitepaper和一些related slides一些有趣的同步性能的讨论。
持有锁的线程解锁锁,然后(或“a”)阻塞的线程被唤醒。如果持有该锁的线程从不释放该锁(可能是因为它在另一个资源上被阻塞),那么就会发生死锁。非旋转锁通常使用wait()/ notify()原语或类似的东西,以便当锁再次可用时通知线程。
锁定采集从未失败。认为它有尚未成功。
当然,也有某些情况下,它会永远成功,但有其中线程通知的失败和hellip的无过渡事件;它只是在等待。
锁定采集确实失败!当你的应用程序发生死锁,你强行杀死进程! ;-) – andersoj 2010-10-18 18:53:28
不,你只是没有给它一个机会。最终,在数十亿年的时间里,一些量子涨落会颠倒右边,其中一个线索会放弃它的锁定。 – erickson 2010-10-18 18:56:15
该死的,我应该把它写入我的下一个国防部性能规格中......量子力学是最终的出路。 – andersoj 2010-10-18 19:02:30