日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CopyOnWriteArrayList简介

發布時間:2025/4/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CopyOnWriteArrayList简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • CopyOnWriteArrayList,寫數組的拷貝,支持高效率并發且是線程安全的,讀操作無鎖的ArrayList。所有可變操作都是通過對底層數組進行一次新的復制來實現。
  • CopyOnWriteArrayList適合使用在讀操作遠遠大于寫操作的場景里,比如緩存。它不存在擴容的概念,每次寫操作都要復制一個副本,在副本的基礎上修改后改變Array引用。CopyOnWriteArrayList中寫操作需要大面積復制數組,所以性能肯定很差
  • 在迭代器上進行的元素更改操作(remove、set和add)不受支持。這些方法將拋出UnsupportedOperationException。
  • 定義

    CopyOnWriteArrayList跟ArrayList一樣實現了List, RandomAccess, Cloneable, Serializable接口,但是沒有繼承AbstractList。

    初始化時候新建一個容量為0的數組。

    add(E e)方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public boolean add(E e) {
    //獲得鎖,添加的時候首先進行鎖定
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
    //獲取當前數組
    Object[] elements = getArray();
    //獲取當前數組的長度
    int len = elements.length;
    //這個是重點,創建新數組,容量為舊數組長度加1,將舊數組拷貝到新數組中
    Object[] newElements = Arrays.copyOf(elements, len + 1);
    //要添加的數據添加到新數組的末尾
    newElements[len] = e;
    //將數組引用指向新數組,完成了添加元素操作
    setArray(newElements);
    return true;
    } finally {
    //解鎖
    lock.unlock();
    }
    }

    從上面來說,每次添加一個新元素都會長度加1,然后復制整個舊數組,由此可見對于寫多的操作,效率肯定不會很好。所以CopyOnWriteArrayList適合讀多寫少的場景。

    add(int index, E element)方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public void add(int index, E element) {
    //同樣也是先加鎖
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
    //獲取舊數組
    Object[] elements = getArray();
    //獲取舊數組長度
    int len = elements.length;
    //校驗指定的index
    if (index > len || index < 0)
    throw new IndexOutOfBoundsException("Index: "+index+
    ", Size: "+len);
    Object[] newElements;
    int numMoved = len - index;
    if (numMoved == 0)//需要插入的位置正好等于數組長度,數組長度加1,舊數據拷貝到新數組
    newElements = Arrays.copyOf(elements, len + 1);
    else {
    //新數組長度增加1
    newElements = new Object[len + 1];
    //分兩次拷貝,第一次拷貝舊數組0到index處的到新數組0到index,第二次拷貝舊數組index到最后的數組到新數組index+1到最后
    System.arraycopy(elements, 0, newElements, 0, index);
    System.arraycopy(elements, index, newElements, index + 1,
    numMoved);
    }
    //index初插入數據
    newElements[index] = element;
    //新數組指向全局數組
    setArray(newElements);
    } finally {
    //解鎖
    lock.unlock();
    }
    }

    set(int index, E element)方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    public E set(int index, E element) {
    //修改元素之前首先加鎖
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
    //獲取原來的數組
    Object[] elements = getArray();
    //index位置的元素
    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();
    }
    }

    get(int index)方法

    讀的時候不加鎖,代碼如下:

    1
    2
    3
    public E get(int index) {
    return get(getArray(), index);
    }
    1
    2
    3
    private E get(Object[] a, int index) {
    return (E) a[index];
    }

    remove()

    remove方法不再過多介紹,看完add和set方法應該就能理解。

    迭代

    內部類COWIterator 實現了ListIterator接口。迭代的時候不能進行remove,add,set等方法,會拋異常。

    迭代速度快,迭代時是迭代的數組快照。

    1
    2
    /** Snapshot of the array */
    private final Object[] snapshot;

    源碼分析

    jdk1.7.0_71

    1
    2
    3
    4
    5
    6
    //鎖,保護所有存取器
    transient final ReentrantLock lock = new ReentrantLock();
    //保存數據的數組
    private volatile transient Object[] array;
    final Object[] getArray() {return array;}
    final void setArray(Object[] a) {array = a;}

    空構造,初始化一個長度為0的數組

    1
    2
    3
    public CopyOnWriteArrayList() {
    setArray(new Object[0]);
    }

    利用集合初始化一個CopyOnWriteArrayList

    1
    public CopyOnWriteArrayList(Collection<? extends E> c) {}

    利用數組初始化一個CopyOnWriteArrayList

    1
    public CopyOnWriteArrayList(E[] toCopyIn) {}

    size() 大小

    1
    public int size() {}

    isEmpty()是否為空

    1
    public boolean isEmpty(){}

    indexOf(Object o, Object[] elements,int index, int fence) 元素索引

    1
    private static int indexOf(Object o, Object[] elements,int index, int fence) {}

    indexOf() 元素索引

    1
    public int indexOf(Object o){}

    indexOf(E e, int index) 元素索引

    1
    public int indexOf(E e, int index) {}

    lastIndexOf(Object o, Object[] elements, int index) 元素索引,最后一個

    1
    private static int lastIndexOf(Object o, Object[] elements, int index) {}

    lastIndexOf(Object o) 元素索引,最后一個

    1
    public int indexOf(E e, int index) {}

    lastIndexOf(E e, int index) 元素索引,最后一個

    1
    public int lastIndexOf(E e, int index) {}

    contains(Object o) 是否包含元素

    1
    public boolean contains(Object o){}

    clone() 淺拷貝

    1
    public Object clone() {}

    toArray() 轉換成數組

    1
    public Object[] toArray(){}

    toArray(T a[]) 轉換成指定類型的數組

    1
    public <T> T[] toArray(T a[]) {}

    E get(int index)獲取指定位置的元素

    1
    public E get(int index){}

    set(int index, E element) 指定位置設置元素

    寫元素的時候,先獲得鎖,finall塊中釋放鎖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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();
    }
    }

    add(E e) 元素添加到末尾

    1
    public boolean add(E e) {}

    add(int index, E element) 指定位置之后插入元素

    1
    public void add(int index, E element){}

    remove(int index)刪除指定位置的元素

    1
    public E remove(int index) {}

    remove(Object o) 刪除第一個匹配的元素

    1
    public boolean remove(Object o) {}

    removeRange(int fromIndex, int toIndex) 刪除指定區間的元素

    1
    private void removeRange(int fromIndex, int toIndex) {}

    addIfAbsent(E e) 如果元素不存在就添加進list中

    1
    public boolean addIfAbsent(E e){}

    containsAll(Collection<?> c)是否包含全部

    1
    public boolean containsAll(Collection<?> c){}

    removeAll(Collection<?> c) 移除全部包含在集合中的元素

    1
    public boolean removeAll(Collection<?> c){}

    retainAll(Collection<?> c) 保留指定集合的元素,其他的刪除

    1
    public boolean retainAll(Collection<?> c){}

    addAllAbsent(Collection<? extends E> c) 如果不存在就添加進去

    1
    public int addAllAbsent(Collection<? extends E> c) {}

    clear() 清空list

    1
    public void clear(){}

    addAll(Collection<? extends E> c)添加集合中的元素到尾部

    1
    public void addAll(Collection<? extends E> c){}

    addAll(int index, Collection<? extends E> c) 添加集合中元素到指定位置之后

    1
    public boolean addAll(int index, Collection<? extends E> c){}

    toString()

    1
    public String toString(){}

    equals(Object o)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public boolean equals(Object o) {
    if (o == this)
    return true;
    if (!(o instanceof List))
    return false;

    List<?> list = (List<?>)(o);
    Iterator<?> it = list.iterator();
    Object[] elements = getArray();
    int len = elements.length;
    for (int i = 0; i < len; ++i)
    if (!it.hasNext() || !eq(elements[i], it.next()))
    return false;
    if (it.hasNext())
    return false;
    return true;
    }

    hashCode()

    1
    public int hashCode{}

    listIterator(final int index)和 listIterator() 返回一個迭代器,支持向前和向后遍歷

    1
    2
    3
    public ListIterator<E> listIterator(final int index) {}

    public ListIterator<E> listIterator() {}

    iterator() 只能向后遍歷

    1
    public Iterator<E> iterator() {}

    subList() 返回部分list

    1
    2
    3
    4
    5
    public List<E> subList(int fromIndex, int toIndex) {
    ...
    return new COWSubList<E>(this, fromIndex, toIndex);
    ...
    }

    參考

    http://www.cnblogs.com/sunwei2012/archive/2010/10/08/1845656.html

    http://my.oschina.net/jielucky/blog/167198


    轉載于:https://www.cnblogs.com/zhangboyu/p/7452542.html

    總結

    以上是生活随笔為你收集整理的CopyOnWriteArrayList简介的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲熟乱 | av在线影片| 黄色片免费在线播放 | 欧美色图在线播放 | 国产区123| 国产传媒在线视频 | av色欲无码人妻中文字幕 | 久久精品国产亚洲av蜜臀色欲 | 国产欧美一区二区在线 | 狠狠操狠狠摸 | 国产男人搡女人免费视频 | 黄色特一级 | 91麻豆精品91久久久久同性 | 男人视频网 | 91精品国产高清91久久久久久 | av资源新版在线天堂 | 人日人视频 | 国产福利片一区二区 | 久久2019| 亚洲 小说区 图片区 都市 | 麻豆网站免费看 | 丰满尤物白嫩啪啪少妇 | 国产精品久久久久久无人区 | 成年人午夜免费视频 | 天天摸天天舔天天操 | 狗爬女子的视频 | 国产精品视频免费网站 | 影音先锋中文字幕在线 | 日韩欧美成人一区 | 午夜一区在线观看 | 天天草综合| 少妇被黑人到高潮喷出白浆 | 成年人免费毛片 | 亚洲精品一区二区18漫画 | 国产三级免费观看 | 亚洲黄色在线观看 | 钰慧的mv视频在线观看 | 欧美整片在线 | 非洲黑寡妇性猛交视频 | 国产真人无码作爱视频免费 | 91日韩在线视频 | 午夜一区二区三区免费 | 亚洲偷怕| 亚洲每日更新 | 国产黄色三级 | 久久亚洲一区二区 | av一卡| 91av不卡| 久草中文在线视频 | 伊人黄色| 又粗又大又硬又长又爽 | 天堂中文在线免费观看 | 婷婷综合一区 | 日韩第1页 | 91精品国产综合久久香蕉 | 午夜视频一区二区 | 欧亚乱熟女一区二区在线 | 亚洲高清视频一区 | 国产一区二区三区免费观看 | 17草在线 | 狂野欧美性猛交xxxxhd | 性欧美18一19性猛交 | 青青草在线播放 | 黄色视屏在线 | 亚洲性色av| 在线观看网页视频 | 桃色网址 | 自拍视频第一页 | 日本午夜免费 | www.99re7.com| 日本精品免费在线观看 | 永久免费无码av网站在线观看 | 动漫女生光屁股 | 日韩伦理大全 | 爱情岛亚洲首页论坛 | 精品一二三区久久aaa片 | 玖玖在线播放 | 和美女啪啪 | 伊人精品影院 | 午夜精品福利一区二区蜜股av | 久久久久久久亚洲 | 久久新视频 | 69社| 国产一av | 亚洲成人诱惑 | 国产无限制自拍 | 欧美福利在线视频 | 国产www免费 | 在线观看一区二区三区视频 | 一区二区三区高清在线 | jizz视频在线观看 | 草草在线影院 | 人人干人人看 | www香蕉视频 | 中国黄色免费网站 | 久久精品综合视频 | 嫩色av | 日韩1区2区3区 | 性色tv |