【发布时间】:2014-08-08 18:04:53
【问题描述】:
不幸的是,我无法提供完整的上下文,因为周围的代码太复杂了。简而言之:
我有一段代码正在等待锁:
synchronized (lock) {
lock.wait();
}
按预期工作。相当简单——它获取锁,当它开始等待时释放它,另一个线程获取锁,然后通知它。
但是,一旦我提供超时,行为就会完全改变。
synchronized (lock) {
lock.wait(60000L);
}
同样,应该相当简单(这在代码中的其他几个地方可以正常工作)。但是,在这种情况下,执行基本上会停止,直到发生超时。我对似乎正在发生的事情的唯一猜测是它在进入等待时没有释放锁——通知程序永远无法获得锁,所以等待会休眠直到超时。更糟糕的是,这是一个阻塞睡眠——没有其他线程能够等待锁,它会强制执行完全同步。
有人对这里可能发生的事情有任何想法吗?这是一个相当简单的功能,在任何时候嵌套同步块都没有什么奇怪的。考虑到通过不提供超时它应该无限期地等待,如果通知器本身被破坏,代码将永远挂起,但事实并非如此。仅在提供超时后才停止工作。
任何想法将不胜感激。
操作系统:OS X 10.8.5
JDK:1.6.0、1.7.0.45 和 1.7.0.67
【问题讨论】:
-
您最好的选择是提供一个简单的测试来说明您所看到的。
-
解决您的误解 - 如果一个线程调用
lock.wait(60000l)它将休眠 1 分钟但也会放弃锁定,因此它不会像您担心的那样阻塞休眠。 -
notify()电话在哪里?您可能会遇到丢失的通知。如果在调用 notify 时在wait()中没有其他线程已被阻塞,notify()不会执行任何操作。 -
如果您在 while 循环中使用此代码块(如您所愿),请将同步块移出,并包装 while 循环,而不仅仅是等待部分。锁的获取和释放会产生很大的开销,建议在循环期间保持锁。
-
是的,但我的意思是,你还没有向我们展示它。直到您向我们展示了一个完整的示例(例如,wait() 是如何发生的和 notify() 是如何发生的),那么我们只能猜测哪里出了问题。
标签: java multithreading mutex