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并发容器 用于读多写少的并发场景
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。