在我的程序中,我正在使用从
创建的Condition对象private static final Lock lock = new ReentrantLock();
像这样:
private static final Condition operationFinished = MyClass.lock.newCondition();
偶尔(因为它总是发生并发问题)我遇到以下行为:
operationFinished.awaitNanos()
- 这应该挂起Thread1并释放锁。根据文档,这种行为是不可能的,因为在awaitNanos()
之后,Thread1首先释放锁,然后暂停。
如果它没有释放锁,那么它就不会暂停,因此Thread2甚至无法试图抓住锁。
有没有人经历过类似的事情?这个错误在100次中发生一次 - 但它仍然表明我要么不以正确的方式使用并发实用程序,要么在java.utils.concurrent。*包中存在某种错误(我怀疑)
更新
回应彼得斯回答:
我观察到以下行为:显然2个线程互相死锁。我可以看到Thread2阻塞(等待锁定)并且同时在Thread1中awaitNanos()
永远不会超时。
答案 0 :(得分:1)
根据您查看此信息的方式,我已经看到很多示例,其中对象上的多个线程wait()
仍然表示它们都持有相同的锁。可能是堆栈跟踪或监控错误导致。
假设您拥有持有锁的thread1,但是在awaitNanos()中,您有Thread2尝试获取lock(),但有时Thread3也持有锁....
我会做一个jstack -l {pid}
来检查可能持有锁的所有线程。
如果锁死锁,awaitLock(也不是wait())将不会返回,因为它必须先获取锁定才能执行此操作。 (除非它被打断)
答案 1 :(得分:1)
您确定等待时间尚未结束吗?如果您等待一段很短的时间(例如几百纳秒),则等待时间可能会在Thread2完全启动之前到期,在这种情况下,Thread1可能会首先重新激活。