gpt4 book ai didi

java - 多条件 vs 多锁

转载 作者:搜寻专家 更新时间:2023-11-01 02:24:07 24 4
gpt4 key购买 nike

对于特定的线程安全数据结构,我需要保护对中央数据结构(即字节数组)的访问。在这种情况下,我选择使用 ReentrantLocks,因为它的公平政策以及创建多个条件的高级功能。

并发的条件比较复杂,列举如下:

  1. 必须专门保护中央字节数组(即一次只有一个线程)。
  2. 两个访问方法(foo 和 bar)必须能够同时运行(如果它们试图访问中央字节数组则在内部阻塞)。
  3. 对任何方法(foo 和 bar)的调用都必须是互斥的(即从不同线程多次调用 foo 将导致一个线程阻塞)。

在我最初的实现中,我选择实现两个嵌套锁,如下所示:

ReentrantLock lockFoo = new ReentrantLock(true);
ReentrantLock lockCentral = new ReentrantLock(true);

Condition centralCondition = lockCentral.newCondition();

public void foo(){
// thread-safe processing code here

lockFoo.lock();
lockCentral.lock();

try{
// accessing code here

try{
// waits upon some condition for access
while(someCondition){
centralCondition.await();
}
}catch(InterruptedException ex){
// handling code here
}

// more processing
}finally{
lockCentral.unlock();
lockFoo.unlock();
}
}

该结构在方法bar 中是等效的,只是使用另一个锁对象lockBar。此外,为了简单起见,该代码已将我更复杂的多条件等待和信号减少为单一条件。

使用这个,我不禁觉得代码似乎不必要的复杂和晦涩,因为不仅嵌套了两个锁,它们共享一个 try-finally,更不用说 lockCentrallockFoo 始终保持的情况下,可以多次释放和重新获取。

相反,我尝试重新组织外部锁(lockFoolockBar)作为 lockCentral 的条件,如下所示:

ReentrantLock lockCentral = new ReentrantLock(true);

Condition fooCondition = lockCentral.newCondition();
Condition centralCondition = lockCentral.newCondition();

boolean isInFoo = false;

public void foo(){
// thread-safe processing code here

lockCentral.lock();

try{
// implement method exclusiveness via fooCondition

try{
while(isInFoo){
fooCondition.await();
}

isInFoo = true;
}catch(InterruptedException ex){
return;
}

// accessing code here

try{
// waits upon some condition for access
while(someCondition){
centralCondition.await();
}
}catch(InterruptedException ex){
// handling code here
}

// more processing
}finally{
isInFoo = false;
fooCondition.signal();

lockCentral.unlock();
}
}

经过一些检查,我无法决定前者是更好的主意还是后者(尤其是包含该随机 boolean 值时)。简化代码的想法似乎导致了更长的代码,在这种情况下非常违反直觉。

是否有一些惯例或令人信服的理由来论证:

  1. 每个锁定上下文使用一个锁(以前的代码,其中不同的锁定原因共享不同的锁)。

  2. 每个锁定资源使用一个锁(后一种代码,其中要保护的中央结构使用单个锁,其他所有内容都作为访问所述结构的条件实现)。

最佳答案

后一个代码与前一个代码的不同之处仅在于使用 fooCondition 手动实现锁 lockFoo(对于 bar 相关的也是如此部分)。

因为这样的锁实现考虑到,foo 临界区几乎与中央 临界区相同,所以保证在没有争用的情况下更快在 foo() 上(在这种情况下永远不会在 fooCondition 上等待)。

除了性能方面的原因,前者的代码是更可取的,因为它是自文档化的。此外,它还可以扩展到需要在没有 lockCentral 的情况下访问受 lockFoo 保护的数据的情况。在那种情况下,手动实现锁会失去其性能增益。

关于java - 多条件 vs 多锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29915786/

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