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

标签 java collections concurrency thread-safety critical-section

假设您有一个共享内存(列表),它将充当“批评者部分”。
现在,考虑一下您始终在这些场景的列表中包含项目,并且您希望您的系统以这种方式运行:

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

  2. 线程 1 想要获取一个项目,同时线程 2 也想要获取一个项目。 这应该会失败。

谢谢

最佳答案

一种可能是将您的 List 包装在一个代理或重写 get 和 add 方法的类中。

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

例如:

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

您可以通过扩展 List 实现并重写 addget 方法(或所有相关方法)来实现此目的,或者使用组合而不是继承,使用代理类将调用转发到列表,但通过显式获取 Lock 来修饰 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();
    }
}
}

关于java - 如何在操作时应用条件线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14566866/

相关文章:

java - super 和 extends 的行为方式相同

java - 哪里使用比较器来排序适配器

java - 如何在多线程代码中避免ConcurrentModificationException

java - 调用 user.getPhotoUrl() Firebase 时出现安全异常

java - 为什么要收集文字?

java - Servlet 中的线程和并发

locking - Playframework 并发作业管理

java - 我的 Spring-Boot 自定义登录表单不起作用 [更新]

java - 如何检查 Cipher 是否支持特定的 key 大小?

java - 如何在项目中找到扩展特定库的所有类?