Java 如何在操作时应用条件线程安全?
假设您有一个共享内存(列表),它将用作“评论部分”。Java 如何在操作时应用条件线程安全?,java,collections,concurrency,thread-safety,critical-section,Java,Collections,Concurrency,Thread Safety,Critical Section,假设您有一个共享内存(列表),它将用作“评论部分”。 现在,考虑一下,在这些场景中,您总是有列表中的项目,并且希望您的系统以这种方式运行: Thread1从列表中获取某些项,而Thread2则希望将该项添加到列表中。允许这种情况(假设我将从开始处获取第一项,并在列表的末尾插入新项-同时!) Thread1想要获取一个项目,同时Thread2也想要获取一个项目。 这应该失败 谢谢一种可能性是将列表包装在一个类中,该类代理或重写get和add方法 这样,您就可以在add方法上使用显式的Lock,以便
现在,考虑一下,在这些场景中,您总是有列表中的项目,并且希望您的系统以这种方式运行:
谢谢一种可能性是将列表包装在一个类中,该类代理或重写get和add方法 这样,您就可以在
add
方法上使用显式的Lock
,以便在任何给定时间只能添加一个线程
例如,见:
您可以通过扩展列表
实现,覆盖添加
和获取
方法(或所有相关方法),或者使用组合而不是继承,使用代理类将调用转发到列表,但是通过显式获取锁来装饰add
和get
一个非常简单的例子如下:
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();
}
}
}
公共类SharedMemory{
私人最终名单记忆列表;
私有静态最终ReentrantLock=新的ReentrantLock();
公共共享内存(){
memoryList=新的ArrayList();
}
公共无效存储项(K项){
memoryList.add(项目);
}
公共K getItem(内部位置){
lock.lock();
试一试{
返回memoryList.get(pos);
}最后{
lock.unlock();
}
}
}
一种可能性是将列表包装在一个类中,该类代理或重写get和add方法
这样,您就可以在add
方法上使用显式的Lock
,以便在任何给定时间只能添加一个线程
例如,见:
您可以通过扩展列表
实现,覆盖添加
和获取
方法(或所有相关方法),或者使用组合而不是继承,使用代理类将调用转发到列表,但是通过显式获取锁来装饰add
和get
一个非常简单的例子如下:
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();
}
}
}
公共类SharedMemory{
私人最终名单记忆列表;
私有静态最终ReentrantLock=新的ReentrantLock();
公共共享内存(){
memoryList=新的ArrayList();
}
公共无效存储项(K项){
memoryList.add(项目);
}
公共K getItem(内部位置){
lock.lock();
试一试{
返回memoryList.get(pos);
}最后{
lock.unlock();
}
}
}
这有什么意义?您是否在谈论不使用synchronized
关键字或并发集合的情况下以某种方式执行此操作?您是否检查了CopyOnWriteArrayList
功能?重点是根据情况1或2,类似于半并发。2应该是线程安全的,1不是,并且在相同的数据结构中实现它,我个人认为这样做是不可能的,但我只是想听听一些专家的意见advice@Quoi:我不熟悉,您认为它合适吗?您需要提供concurrenthashmap
的细粒度锁定。这里有什么意义?您是否在谈论不使用synchronized
关键字或并发集合的情况下以某种方式执行此操作?您是否检查了CopyOnWriteArrayList
功能?重点是根据情况1或2,类似于半并发。2应该是线程安全的,1不是,并且在相同的数据结构中实现它,我个人认为这样做是不可能的,但我只是想听听一些专家的意见advice@Quoi:我不熟悉这个,你认为它合适吗?你需要提供concurrenthashmap
的粒度锁定。它被认为是粒度锁定吗?我不确定你的意思。。。这里的锁定可以是您所需要的粒度,只需对其进行微调,以仅锁定需要“保护”的特定代码块即可。@JavaSa锁定粒度只是指您锁定的代码部分的大小。例如,如果您只应用了一个全局锁,那么它的粒度非常小。但是,如果每个方法只锁定一个或两个操作,这是非常精细的粒度。它被认为是粒度锁定吗?我不知道你的意思。。。这里的锁定可以是您所需要的粒度,只需对其进行微调,以仅锁定需要“保护”的特定代码块即可。@JavaSa锁定粒度只是指您锁定的代码部分的大小。例如,如果您只应用了一个全局锁,那么它的粒度非常小。但是,如果每个方法只锁定一个或两个操作,这是非常精细的粒度。