2014-10-17 93 views
0

我有一个数组,这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锁的锁。

我该怎么办呢?

+0

你的意思是说你的方法应该是'synchronized'吗? – 2014-10-17 08:50:14

+0

@ShishirKumar不,我的意思是说,如果一个线程访问数组的第一个位置,另一个线程可以访问其他位置,没有同步,但具有并行性 – 2014-10-17 08:51:55

+0

哦,我现在明白了。 – 2014-10-17 08:53:00

回答

1

您需要为每个单元格设置一个锁定对象。如果你永远只能有两个值,则有

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

在类的标题,然后方法的声明synchronized块使用锁1和的methodB有使用锁2 synchronized块都有。然后每个“单元格”被独立锁定。

例如

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

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

如果你将有很多独立的细胞,那么为什么不宣布哪些有锁在里面,并且用作包装的每个单元格的值的单元格类。然后你可以有一个更一般的方法来访问一个线程安全的单元格的内容。

例如

class Cell { 
    private Object lock; 
    private Object value; 

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

但是,目前还不清楚在线程安全方面您会从中获得什么。

+0

谢谢你的回答,你能否给我提供一个小段子,我有点困惑。 – 2014-10-17 08:55:09

+0

我会把它放在帖子中。 – 2014-10-17 08:56:46

1

如果您想为阵列中的每个元素分别设置一个锁,您可以使用一组Lock对象来匹配其他阵列,并依次锁定每个单元。

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

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

+0

“并发集合”在这里会有帮助吗?如果程序需要锁定对某个集合中某个特定成员的访问权限,那么无论该集合对象本身是否为线程安全的,都需要该锁定。线程安全性是不可编辑的:如果您完全使用线程安全组件构建程序,那么它本身并不会使您的程序线程安全。 – 2014-10-17 15:20:38

1

从我所了解的问题来看,java.util.concurrent中的并发列表实现可能对您有所帮助。

你应该在这个包中寻找CopyOnWriteArrayList类。

请参阅前面的SO问题,它可以很好地解释它。

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

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

希望这可以帮助你。

+0

问题更新,我不能创建更多的对象实例,我必须只与一个对象实例一起工作。 – 2014-10-17 09:02:06