看jetty源码时看到的CopyOnWrite容器
来源:互联网 发布:工商银行淘宝灵通卡 编辑:程序博客网 时间:2024/06/11 14:39
1、首先说说CopyOnWrite容器是干啥的:
在jdk中CopyOnWrite容器有两个,一个是CopyOnWriteArrayList,另一个是CopyOnWriteArraySet,CopyOnWriteArrayList是List的子类,CopyOnWriteArraySet是Set的子类,这两个类达到的目标都是实现线程安全的,先目睹一下CopyOnWriteArrayList的源码
本类中定义的属性
private static final long serialVersionUID = 8673264195747942595L; /** The lock protecting all mutators */ transient final ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private volatile transient Object[] array;
上面的三个属性:第一个是序列化版本ID,和JVM有关;第二个是可重入锁ReentrantLock,这个属性是不可更改的(final)和不被序列化的(transient),第三个是volatile transient的对象数组
下面看看CopyOnWriteArrayList的添加和删除的方法实现
1. Set方法
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(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 oldValue; } finally { lock.unlock(); } }
2. 在数组最后添加元素的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(); } }
3. 在数组中替换元素的Add方法
public void add(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; if (index > len || index < 0) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len); Object[] newElements; int numMoved = len - index; if (numMoved == 0) newElements = Arrays.copyOf(elements, len + 1); else { newElements = new Object[len + 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index, newElements, index + 1, numMoved); } newElements[index] = element; setArray(newElements); } finally { lock.unlock(); } }
4. Remove方法
public E remove(int index) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; E oldValue = get(elements, index); int numMoved = len - index - 1; if (numMoved == 0) setArray(Arrays.copyOf(elements, len - 1)); else { Object[] newElements = new Object[len - 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index + 1, newElements, index, numMoved); setArray(newElements); } return oldValue; } finally { lock.unlock(); } }
5. addAll方法
public boolean addAll(Collection<? extends E> c) { Object[] cs = c.toArray(); if (cs.length == 0) return false; final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + cs.length); System.arraycopy(cs, 0, newElements, len, cs.length); setArray(newElements); return true; } finally { lock.unlock(); } }
.。。。。。。。
从上面所有的方法可以看出,所有操作array的方法都会锁住,然后复制一份,再操作复本,完成之后再让array指向新的地址。这样也不难想到这是一个线程安全的类,对于读取属性array没有添加锁,也就是在读取的时候可能会读取到旧数据,在修改属性array中添加了锁,也就是在添加的时候是线程安全的。
从jdk api文档也可以看到的说法是这是ArrayList的线程安全的一个变体。
2、CopyOnWrite容器有什么用处
这个类的出现让我想到了项目中的一些写在config配置文件中的和写在数据表中的一些系统配置可以使用该类实现,当然这个是绝对不能用来做并发时的自增的啦。
0 0
- 看jetty源码时看到的CopyOnWrite容器
- CopyOnWrite容器
- CopyOnWrite容器
- CopyOnWrite容器
- CopyOnWrite容器
- Java中的CopyOnWrite容器
- Java中的CopyOnWrite容器
- Java中的CopyOnWrite容器
- Java中的CopyOnWrite容器
- Java中的CopyOnWrite容器
- CopyOnWrite容器使用总结
- Java中的CopyOnWrite容器
- 并发容器CopyOnWrite
- Java中的CopyOnWrite容器
- 高并发容器--CopyOnWrite
- Java中的CopyOnWrite容器
- Java中的copyOnWrite容器
- CopyOnWrite容器理解
- 安全标准
- skb->truesize,len,datalen,size,等的区别
- GitHub上README写法暨GFM语法解读
- $.ajax的简单用法
- 商户端 和 支付宝 通讯验证
- 看jetty源码时看到的CopyOnWrite容器
- ios基于UITableViewController实现列表
- PyGobject(二十)布局容器之ComboBox
- 理解$watch ,$apply 和 $digest --- 理解数据绑定过程
- io
- POJ-1679 The Unique MST
- 策略模式
- backup incremental level 1 database
- php 防注入的一些总结