6

我看到有人用来 assert !Thread.holdsLock(lock)避免死锁。

这是什么目的?如果锁对象被另一个线程持有,断言会导致代码立即退出吗?

4

4 回答 4

7

方法的javadoc说:

true当且仅当当前线程持有指定对象的监视器锁时返回。

(强调我的)

因此,断言检查当前线程是否持有给定锁对象的监视器锁。

请注意,断言用于检查不变量,并且可以禁用。它们不应该用于防止死锁。if应该使用定期测试来做到这一点。

于 2012-06-10T09:25:37.670 回答
3

assert关键字用于捕获错误;它不应该被用来控制程序流程。所以要么这是一个误解,要么有人做错了什么。
更有可能的是,该人将断言语句放在那里以防止开发人员在该代码段中添加死锁风险。

像这样:

assert !Thread.holdsLock(lock) : 
"Don't call this method while holding the lock." + 
"This method tries to acquire lock2 and that may cause a deadlock.";
于 2012-06-10T09:30:53.643 回答
1

当线程一次获取并持有多个锁时,死锁是一个常见问题。避免此问题的一种简单方法是确保始终以相同的顺序获取多个锁并以相同的(反向)顺序释放。所以锁定(A)然后锁定(B)。解锁(B)然后解锁(A)。看起来很简单,但这些乱序锁定/解锁问题有一种潜入代码的方式。

因此,在我们锁定 A 之前,请确保我们还没有持有 B。

断言 !Thread.holdsLock(B)

于 2018-09-24T19:24:19.370 回答
0

Thread.holdsLock(lock)仅用于检查调用线程是否拥有,仅此lock而已。

不会防止死锁(拥有这样的方法会很棒:))

于 2012-06-10T09:31:18.683 回答