并发:Condition.awaitNanos()没有释放锁

时间:2012-03-07 14:45:34

标签: java concurrency locking conditional-statements

在我的程序中,我正在使用从

创建的Condition对象
private static final Lock lock = new ReentrantLock();
像这样:

private static final Condition operationFinished = MyClass.lock.newCondition();

偶尔(因为它总是发生并发问题)我遇到以下行为:

  1. Thread1获取锁
  2. Thread1调用operationFinished.awaitNanos() - 这应该挂起Thread1并释放锁。
  3. Thread2尝试获取相同的锁,但调试输出显示Thread1仍然持有锁!
  4. 根据文档,这种行为是不可能的,因为在awaitNanos()之后,Thread1首先释放锁,然后暂停。 如果它没有释放锁,那么它就不会暂停,因此Thread2甚至无法试图抓住锁。

    有没有人经历过类似的事情?这个错误在100次中发生一次 - 但它仍然表明我要么不以正确的方式使用并发实用程序,要么在java.utils.concurrent。*包中存在某种错误(我怀疑)

    更新

    回应彼得斯回答:

    我观察到以下行为:显然2个线程互相死锁。我可以看到Thread2阻塞(等待锁定)并且同时在Thread1中awaitNanos()永远不会超时。

2 个答案:

答案 0 :(得分:1)

根据您查看此信息的方式,我已经看到很多示例,其中对象上的多个线程wait()仍然表示它们都持有相同的锁。可能是堆栈跟踪或监控错误导致。

假设您拥有持有锁的thread1,但是在awaitNanos()中,您有Thread2尝试获取lock(),但有时Thread3也持有锁....

我会做一个jstack -l {pid}来检查可能持有锁的所有线程。

如果锁死锁,awaitLock(也不是wait())将不会返回,因为它必须先获取锁定才能执行此操作。 (除非它被打断)

答案 1 :(得分:1)

您确定等待时间尚未结束吗?如果您等待一段很短的时间(例如几百纳秒),则等待时间可能会在Thread2完全启动之前到期,在这种情况下,Thread1可能会首先重新激活。