- 浏览: 147776 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
EclipseEye:
fair_jm 写道不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程 -
fair_jm:
不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程
List
-----------
1.ArrayList(jdk1.5以前版本中Vector)
2.LinkedList(jdk1.5以前版本中Stack)
3.CopyOnWriteArrayList
----------------------------------------CopyOnWriteArrayList----------------------------------------
CopyOnWriteArrayList 用在“读多,改少”的“并发”应用中。
不存在“扩容”的概念,每次写操作(add or remove)都要copy一个副本,在副本的基础上修改后改变array引用---所以称为“CopyOnWrite”,因此在写操作是加锁,并且对整个list的copy操作时相当耗时的,过多的写操作不推荐使用该存储结构。
CopyOnWriteArrayList的类层次结构
CopyOnWriteArrayList的全局变量
CopyOnWriteArrayList的构造方法
CopyOnWriteArrayList的get方法
CopyOnWriteArrayList的set方法
CopyOnWriteArrayList的add方法
-----------
1.ArrayList(jdk1.5以前版本中Vector)
2.LinkedList(jdk1.5以前版本中Stack)
3.CopyOnWriteArrayList
----------------------------------------CopyOnWriteArrayList----------------------------------------
CopyOnWriteArrayList 用在“读多,改少”的“并发”应用中。
不存在“扩容”的概念,每次写操作(add or remove)都要copy一个副本,在副本的基础上修改后改变array引用---所以称为“CopyOnWrite”,因此在写操作是加锁,并且对整个list的copy操作时相当耗时的,过多的写操作不推荐使用该存储结构。
CopyOnWriteArrayList的类层次结构
public class CopyOnWriteArrayList <E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
CopyOnWriteArrayList的全局变量
transient final ReentrantLock lock = new ReentrantLock();//全局锁 private volatile transient Object[] array;//volatile(修改可见)类型的数组array //内部的实现中仅通过array的get和set方法对其进行操作 final Object[] getArray() { return array; } final void setArray(Object[] a) { array = a; }
CopyOnWriteArrayList的构造方法
/** * 创建一个空的list,默认容量为0,这个和ArraList中的默认10不同,主要是因为在对CopyOnWriteArrayList的修改操作时都是先copy *一个数组(容量+1或容量-1),处理后再把引用赋给array的,不存在扩容的情况,所以当初始化时就没必要指定长度了。 */ public CopyOnWriteArrayList() { setArray(new Object[0]); } //通过已有集合构建CopyOnWriteArrayList public CopyOnWriteArrayList(Collection<? extends E> c) { Object[] elements = c.toArray(); if (elements.getClass() != Object[].class) elements = Arrays.copyOf(elements, elements.length, Object[].class);//copy一个数组 setArray(elements);//把array引用指向新的数组 } //通过给定的数组创建List public CopyOnWriteArrayList(E[] toCopyIn) { setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); }
CopyOnWriteArrayList的get方法
//get操作 ,不加锁 public E get(int index) { //直接定位到数组的index下标处,没有加锁操作 //(array是volatile类型的,volatile的 happen-before原则就是所有的“写操作”都在“读操作”前发生,保证了数据的一致性) return (E)(getArray()[index]); }
CopyOnWriteArrayList的set方法
//set 修改元素操作,加锁 public E set(int index, E element) {//在指定的位置index处设置element final ReentrantLock lock = this.lock; lock.lock();//加锁 try { Object[] elements = getArray(); Object oldValue = elements[index];//获得数组中index坐标下的值 if (oldValue != element) {//如果传入的element和目前坐标index处的值不同 int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len);//copy一个数组副本 newElements[index] = element;//并把指定index处的值进行替换 setArray(newElements);//array引用指向新的数组 } else { // Not quite a no-op; ensures volatile write semantics setArray(elements);//保证volatile的happen-before原则 } return (E)oldValue; } finally { lock.unlock();//解锁 } }
CopyOnWriteArrayList的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;//在新数组的最后一个位置加入e元素 setArray(newElements); return true; } finally { lock.unlock();//解锁 } } //在指定的index处加入元素element,加锁 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);//index前的元素 System.arraycopy(elements, index, newElements, index + 1, numMoved);//index后的元素 } newElements[index] = element; setArray(newElements); } finally { lock.unlock();//解锁 } }CopyOnWriteArrayList的remove方法
//remove 删除操作,加锁 public E remove(int index) { final ReentrantLock lock = this.lock; lock.lock();//加锁 try { Object[] elements = getArray(); int len = elements.length; Object oldValue = 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 (E)oldValue; } finally { lock.unlock();//解锁 } } //remove参数是元素对象,需要遍历比较,加锁 public boolean remove(Object o) { final ReentrantLock lock = this.lock; lock.lock();//加锁 try { Object[] elements = getArray(); int len = elements.length; if (len != 0) { // Copy while searching for element to remove // This wins in the normal case of element being present int newlen = len - 1; Object[] newElements = new Object[newlen];//创建一个length-1的数组 for (int i = 0; i < newlen; ++i) { if (eq(o, elements[i])) { // 如果找到了该元素,就把其后继拷贝到新数组中 for (int k = i + 1; k < len; ++k) newElements[k-1] = elements[k]; setArray(newElements); return true; } else //把其前面的节点一一设置到新数组中去 newElements[i] = elements[i]; } // 特殊的判断:和最和一个元素比较(如果刚好是最后一个,就大大减少比较) if (eq(o, elements[newlen])) { setArray(newElements); return true; } } return false; } finally { lock.unlock();//解锁 } }
发表评论
-
Nio Socket
2013-05-16 05:53 0asfda -
结合jdk源码解读,Error Exception
2013-05-10 04:00 0/* * @(#)Error.java 1.17 05/11 ... -
从不同的角度,重新审视class和interface
2013-05-07 03:40 0java开发中,对应class和interface的基本区别都 ... -
java.lang.Object
2013-05-07 03:35 0/* * @(#)Object.java 1.73 06/0 ... -
反射机制+类加载机制
2013-02-18 01:30 0反射机制+类加载机制 -
并发专题----使用开源软件Amino构建并发应用程序/多线程运行时分析工具MTRAT
2013-02-14 00:50 1361使用开源软件构建并发 ... -
并发专题 ---- 线程安全
2013-02-14 00:50 737线程安全 ================== ... -
并发专题 --- 锁
2013-02-14 00:50 792相比于synchronized,ReentrantLock 提 ... -
并发专题 ----(JMM)java内存模型
2013-02-14 00:50 530Java 内存模型 ------------ ... -
并发专题 ---java.util.concurrent 包
2013-02-13 02:26 1824java.util.concurrent 包 原 ... -
集合框架 Queue篇(8)---PriorityBlockingQueue、SynchronousQueue
2013-02-07 12:40 1291Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(7)---LinkedBlockingDeque
2013-02-07 12:40 843Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(6)---LinkedBlockingQueue
2013-02-07 12:39 820Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(5)---ArrayBlockingQueue
2013-02-06 10:39 694Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(4)---阻塞队列和生产者-消费者模式、DelayQueue
2013-02-06 10:39 983Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(3)---ConcurrentLinkedQueue
2013-02-06 10:38 1031Queue ------------ 1.ArrayDequ ... -
集合框架 Queue篇(2)---PriorityQueue
2013-02-06 10:38 820Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(1)---ArrayDeque
2013-02-06 10:38 917Queue ------------ 1.ArrayDeq ... -
集合框架 Set篇---HashSet、LinkedHashSet、TreeSet、CopyOnWriteArraySet、ConcurrentSkipList
2013-02-05 08:43 1467Set --------- 1.HashSet 2.Link ... -
集合框架 List篇(1)---ArrayList、LinkedList
2013-02-05 08:42 898List ----------- 1.ArrayList(jd ...
评论