CopyOnWriteArrayList简介说明

戚薇 Java经验 发布时间:2023-05-21 07:45:14 阅读数:7024 1
下文笔者讲述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并发容器
   用于读多写少的并发场景 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202305/16846263776561.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者