博客
关于我
聊聊并发-Java中的CopyOnWrite容器
阅读量:779 次
发布时间:2019-03-24

本文共 2540 字,大约阅读时间需要 8 分钟。

CopyOnWrite容器:高效的并发编程解决方案

CopyOnWrite容器的概念

CopyOnWrite(写时复制),是一种优化策略,主要用于解决共享资源的并发访问问题。在程序设计中,尤其是在多线程环境下,直接共享同一份资源可能导致竞态条件和死锁。CopyOnWrite通过复制资源的方式,实现了对共享资源的安全访问。

CopyOnWrite容器的实现原理

CopyOnWrite容器的核心思想是:当资源被修改时,首先创建一个新的副本,然后对副本进行操作。这种方式避免了直接操作共享资源的竞态条件问题。

CopyOnWriteArrayList的实现

为了更好地理解CopyOnWrite容器的工作原理,我们可以分析Java的CopyOnWriteArrayList。在添加元素时,容器会复制当前的数组,并在新数组中添加元素。原数组的引用随后被指向新数组。这种方式确保了读操作可以在不加锁的情况下进行,因为读操作始终操作的是旧数组。

public boolean add(T e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}

CopyOnWriteMap的实现

为了满足更复杂的键值存储需求,我们可以实现一个简单的CopyOnWriteMap。其核心思想与CopyOnWriteArrayList类似:在修改时创建新副本,并对副本进行操作。

public class CopyOnWriteMap
implements Map
, Cloneable {
private volatile Map
internalMap;
public CopyOnWriteMap() {
internalMap = new HashMap
();
}
public V put(K key, V value) {
synchronized (this) {
Map
newMap = new HashMap
(internalMap); V val = newMap.put(key, value); internalMap = newMap; return val; } } public V get(Object key) { return internalMap.get(key); } public void putAll(Map
newData) { synchronized (this) { Map
newMap = new HashMap
(internalMap); newMap.putAll(newData); internalMap = newMap; } } }

CopyOnWrite容器的应用场景

CopyOnWrite容器在读多写少的并发场景中表现尤为出色。例如:

黑名单服务系统

package com.ifeve.book;
import java.util.Map;
import com.ifeve.book.forkjoin.CopyOnWriteMap;
public class BlackListServiceImpl {
private static CopyOnWriteMap
blackListMap = new CopyOnWriteMap
(1000);
public static boolean isBlackList(String id) {
return blackListMap.get(id) != null;
}
public static void addBlackList(String id) {
blackListMap.put(id, Boolean.TRUE);
}
public static void addBlackList(Map
ids) {
blackListMap.putAll(ids);
}
}

CopyOnWrite容器的优缺点

优点

  • 高效的读写分离:CopyOnWrite容器支持在不加锁的情况下进行读操作,从而减少了竞争条件。
  • 简单的实现:相比其他并发容器(如ConcurrentHashMap),CopyOnWrite容器的实现较为简单。
  • 缺点

  • 内存占用:写时复制会增加内存消耗,尤其是在处理大量数据时,可能导致GC问题。
  • 一致性问题:CopyOnWrite容器无法保证写入的数据能够实时读取。
  • CopyOnWrite容器的适用性

    CopyOnWrite容器适用于以下场景:

  • 读多写少的场景:适合需要频繁读取但少量写入的应用。
  • 对一致性要求不高的场景:适合不需要实时更新的场景。
  • 结论

    CopyOnWrite容器通过写时复制机制,为并发编程提供了一种高效的解决方案。它在读多写少的场景中表现优异,但在内存占用和一致性方面存在一定的局限性。开发者在使用时,需要根据具体需求权衡其优缺点。

    转载地址:http://wufuk.baihongyu.com/

    你可能感兴趣的文章
    PowerDesigner使用教程:不显示背景网格
    查看>>
    PowerDesigner使用教程:创建数据模型以及导出
    查看>>
    PowerDesigner使用教程:右侧工具栏显示/隐藏
    查看>>
    PowerDesigner使用教程:导出sql文件以及解决中文乱码问题
    查看>>
    PowerDesigner使用教程:时间字段设置
    查看>>
    PowerDesigner使用教程:给字段添加唯一约束
    查看>>
    QGIS中怎样设置图层样式并导出地图样式
    查看>>
    PowerDesigner使用笔记
    查看>>
    QGIS中怎样实现数据坐标系转换
    查看>>
    PowerDesigner学习--基本步骤
    查看>>
    PowerDesigner导出Report通用报表
    查看>>
    PowerDesigner教程系列(二)概念数据模型
    查看>>
    Powerdesigner显示表的comment和列的comment的方法
    查看>>
    PowerDesigner最基础的使用方法入门学习
    查看>>
    PowerDesigner版本控制器设置权限
    查看>>
    PowerDesigner生成数据模型并导出报告
    查看>>
    QGIS中导入dwg文件并使用GetWKT插件获取绘制元素WKT字符串以及QuickWKT插件实现WKT显示在图层
    查看>>
    PowerDesigner逆向工程从SqlServer数据库生成PDM(图文教程)
    查看>>
    PowerEdge T630服务器安装机器学习环境(Ubuntu18.04、Nvidia 1080Ti驱动、CUDA及CUDNN安装)
    查看>>
    PowerPC-object与elf中的符号引用
    查看>>