gpt4 book ai didi

java - 如果 ReentrantLock 被锁定等待但不锁定锁

转载 作者:行者123 更新时间:2023-11-29 04:20:21 25 4
gpt4 key购买 nike

我的代码中有一个 ReentrantLock,我想用它每秒清除一次数组;我不希望其他线程在清除数组时更改数组,但如果我当前没有清除数组,则其他线程不必等待,如下所示:

public void addToArray(Object a) {
lock.waitforunlock(); //not a real method just to clarify my intentions
array.add(a);
}

为了更好地阐明我的意图,我将解释该过程:netty eventloop 将调用我的网络处理程序,然后该网络处理程序将调用之前的 addToArray 方法,每秒一次,我的主线程将永远不会是 Netty 线程数组,此时每个 netty 线程都必须等到它完成!注意:addToArray 方法是线程安全的,我不想同步它,因为这样事件循环的漏洞点就没用了。

最佳答案

没有 API 方法可以完全满足您的要求。

最有效的方法是这样的:

try {
lock.lock();
} finally {
lock.unlock();
}

换句话说,暂时捕获锁然后释放它。

但是问题来了。

  1. 一般来说,在您释放锁的瞬间,其他线程可能会立即获取它。因此,您的 array.add() 调用可能会与其他一些对 array 执行操作的线程同时发生。即使您的用例意味着另一个线程获取锁的可能性很小,它仍然可能发生;例如如果您的服务器负载过重,并且当前线程在释放锁后立即被抢占。

  2. 假设您正在 array.add() 中执行内存写入。除非以适当的同步方式执行,否则这些更新可能对其他线程不可见。 (你说 “addToArray 方法是线程安全的”,但如果没有清晰、详细地解释你的意思,我会不愿意说这个代码是线程安全的。 )

  3. 如果您在这里尝试做的是在发生其他事情之后array.add(),那么测试锁/等待它被释放不会告诉您如果事件真的发生了。它只告诉您,测试成功时并没有发生这种情况。

简而言之,我怀疑在进行更新之前等待释放锁实际上是一个正确的解决方案......无论您如何实现等待。


另一种看待这个问题的方式。

  • 如果 array.add() 是完全线程安全的,并且无论是否有其他线程持有锁都可以正常工作,为什么您需要测试锁?调用方法即可。

  • 如果您实际上是在尝试让 array.add() 调用发生在某个与释放锁同时发生的事件之后,请使用循环屏障或类似方法。


注意:我阅读并试图理解您的解释,但我对您所说的内容感到困惑。我认为是由于“语言问题”。

关于java - 如果 ReentrantLock 被锁定等待但不锁定锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49695996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com