CopyOnWriteArrayList简介说明
下文笔者讲述CopyOnWriteArraylist简介说明
CopyOnWrite简介
Copy-On-Write(COW)
是一种用于程序设计中的优化策略
COW的设计思路:
大家都在共享同一个内容,当某个人想要修改这个内容的时候
才会真正把内容Copy出去形成一个新的内容然后再改
CopyOnWrite容器简介
CopyOnWrite容器(写时复制的容器)
当向一个容器添加元素的时候,不直接往当前容器添加
而先将当前容器进行Copy,复制出一个新的容器,然后向新的容器里添加元素
添加完元素之后,
再将原容器的引用指向新的容器
采用CopyOnWrite容器的优点:
可对CopyOnWrite容器进行并发的读,而无需加锁
CopyOnWrite容器当前容器不会添加任何元素
所以CopyOnWrite容器也是一种读写分离的思想,读和写是不同容器
CopyOnWriteArrayList实现原理
了解CopyOnWrite的实现原理
我们可以从add和读方法上分析其原理
add方法
public boolean add(E 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();
}
}
set方法
public E set(int index, E element) {
//获得锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
Object oldValue = elements[index];
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return (E)oldValue;
} finally {
lock.unlock();
}
}
读的时候不需要加锁,如果读的时候有多个线程正在向ArrayList添加数据,读还是会读到旧的数据,因为写的时候不会锁住旧的ArrayList。
get方法
读数据时,无需加锁 当多个线程向ArrayList中添加数据时, 此时读数据,还会读取到旧数据
public E get(int index) {
return get(getArray(), index);
}
CopyOnWriteHashMap实现
jdk没有实现CopyOnWriteHashMap 下文是笔者实现的CopyOnWriteHashMap 如下所示
package com.java265.base.copyonwrite;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
public class CopyOnWriteHashMap implements Map, Cloneable {
private volatile Map internalMap;
public CopyOnWriteHashMap() {
internalMap = new HashMap();
}
public int size() {
return internalMap.size();
}
public boolean isEmpty() {
return internalMap.isEmpty();
}
public boolean containsKey(Object key) {
return internalMap.containsKey(key);
}
public boolean containsValue(Object value) {
return internalMap.containsValue(value);
}
public V get(Object key) {
return internalMap.get(key);
}
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 remove(Object key) {
synchronized (this) {
Map newMap = new HashMap(internalMap);
V val = newMap.remove(key);
internalMap = newMap;
return val;
}
}
public void putAll(Map m) {
synchronized (this) {
Map newMap = new HashMap(internalMap);
newMap.putAll(m);
internalMap = newMap;
}
}
public void clear() {
synchronized (this) {
Map newMap = new HashMap(internalMap);
newMap.clear();
internalMap = newMap;
}
}
public Set keySet() {
return internalMap.keySet();
}
public Collection values() {
return internalMap.values();
}
public Set entrySet() {
return internalMap.entrySet();
}
}
CopyOnWrite使用场景
CopyOnWrite并发容器 用于读多写少的并发场景
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


