锁定数组的单元格

时间:2014-10-17 08:45:57

标签: java multithreading

我有一个2个值的数组,我想保持细胞独立。因此,例如当一个线程获取第一个位置的锁时,该线程不会阻塞整个结构。

public DataStructure(int r, int i) {
        this.r = r;
        this.i = i;
        values = new ArrayList<Integer>;
        values.add(i);
        values.add(r);
        [...]
}
public void methodA() {
         lock.lock();
          [...]
          values.get(0);
          lock.unlock();    
}
public void methodB() {
         lock.lock();
          [...]
          values.get(1);
          lock.unlock();    
}

使用此代码,当一个线程获得methodA上的锁定时,不可能使用其他线程来锁定methodB

我怎么做?

3 个答案:

答案 0 :(得分:2)

您需要为每个单元格设置一个锁定对象。如果您只有两个值,那么

Object lock1 = new Object();
Object lock2 = new Object();

在类的标题中然后让方法A使用lock1声明一个synchronized块,而methodB使用lock2声明一个synchronized块。然后每个&#34;单元&#34;是独立锁定的。

e.g。

public void methodA() {
     synchronized(lock1) {
      [...]
      values.get(0);
      }  
}

public void methodB() {
     synchronized(lock2) {
      [...]
      values.get(1);
      }  
}

如果您将拥有大量独立单元格,那么为什么不声明一个具有锁定的单元格类,并将其用作每个单元格值的包装器。然后,您可以使用更通用的方法来访问线程安全的单元格内容。

e.g。

class Cell {
    private Object lock;
    private Object value;

    public void doSomething() {
        synchronized(lock) {
            // something happens here with the value
        }
    }
}

但是,目前还不清楚您在线程安全方面的收获是什么。

答案 1 :(得分:1)

如果你想为数组中的每个元素分别使用一个锁,你可以使用Lock个对象数组来匹配你的另一个数组,并依次锁定每个单元格。

或者,您可以考虑使用其中一个并发收藏集,例如CopyOnWriteArrayListConcurrentHashMap,具体取决于您的需求。

这些集合是线程安全的,并为您处理锁定。

答案 2 :(得分:1)

根据我对该问题的理解,java.util.concurrent中的并发列表实现可能对您有所帮助。

您应该在此包中寻找CopyOnWriteArrayList课程。

参考之前的SO问题,这完美地解释了它。

https://stackoverflow.com/a/10397154/2867032

  

CopyOnWriteArrayList类是一个有趣的案例。它避免了   只读操作(如get和。)的并发瓶颈   包含,但它通过在变异中做更多的工作来做到这一点   操作,以及修改可见性规则。而且,   变异操作锁定整个列表,因此是一个   并发瓶颈。这些属性意味着   CopyOnWriteArrayList无法被称为通用并发   列表。

希望这会对你有所帮助。