如何在操作时应用条件线程安全?

时间:2013-01-28 16:45:29

标签: java collections concurrency thread-safety critical-section

考虑你有一个共享记忆(List),它将作为“批评部分” 现在,请考虑您在这些方案的列表中始终有项目,并且您希望系统以这种方式运行:

  1. Thread1从列表中获取一些项目,同时Thread2想要将项目添加到列表中。允许这种情况(假设我将从开始采取第一项并在列表末尾插入新项目 - 在相同的时间!)。

  2. Thread1想要获得一个项目,同时Thread2也想获得一个项目。 这应该失败。

  3. 感谢

1 个答案:

答案 0 :(得分:1)

一种可能性是将List包装在代理或覆盖get和add方法的类中。

这样,您可以在Lock方法上使用显式add,这样在任何给定时间只能添加一个线程。

参见例如:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

你可以通过扩展List实现,覆盖addget方法(或所有相关方法),或者使用组合而不是继承来实现这一点,将调用转发到列表的代理类,但使用显式获取锁来装饰addget

一个非常简单的例子就是:

public class SharedMemory<K> {

private final List<K> memoryList;
private static final ReentrantLock lock = new ReentrantLock();

public SharedMemory() {
    memoryList = new ArrayList<>();
}

public void storeItem(K item) {
    memoryList.add(item);
}

public K getItem(int pos){
    lock.lock();
    try{
        return memoryList.get(pos);
    } finally {
        lock.unlock();
    }
}
}