欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的CopyOnWriteArrayList詳解

 更新時(shí)間:2023年12月18日 10:38:12   作者:暴躁的程序猿啊  
這篇文章主要介紹了Java中的CopyOnWriteArrayList詳解,ArrayList單線程下是安全的 但是多線程下存在不安全的問(wèn)題,多線程下是不安全的,需要的朋友可以參考下

引入

ArrayList單線程下是安全的 但是多線程下存在不安全的問(wèn)題

多線程下是不安全的

例如: 我們開(kāi)啟多個(gè)線程向arraylist添加數(shù)據(jù)

public class ListTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                list.add("a");
            System.out.println(list);
            }).start();
        }
    }
}

報(bào)出異常

在這里插入圖片描述

解決這個(gè)問(wèn)題我們可以使用集合工具類(lèi)創(chuàng)建線程安全的ArrayList

  List<String> strings = Collections.synchronizedList(new ArrayList<String>());
    for (int i = 0; i < 101; i++) {
        new Thread(()->{
            strings.add("a");
            System.out.println(strings);
        }).start();
    }
}

在這里插入圖片描述

但加入synchronized此時(shí)效率較低

所以我們可以使用juc包中的 CopyOnWriterArrayList

CopyOnWriterArrayList

CopyOnWriteArrayList (拷貝寫(xiě)數(shù)組) 是ArrayList線程安全的集合

其中所有可變操作(add、set等等)都是通過(guò)對(duì)底層數(shù)組進(jìn)行一次新的復(fù)制來(lái)實(shí)現(xiàn)的。

適合場(chǎng)景:讀多、寫(xiě)少的并發(fā)場(chǎng)景

cow思想

它不存在“擴(kuò)容”的概念,每次寫(xiě)操作(add 、remove)都要copy一個(gè)副本,在副本的基礎(chǔ)上修改后改變array引用,所以稱(chēng)為“CopyOnWrite”,因此在寫(xiě)操作是加鎖,并且對(duì)整個(gè)list的copy操作時(shí)相當(dāng)耗時(shí)的,過(guò)多的寫(xiě)操作不推薦使用該存儲(chǔ)結(jié)構(gòu)。

讀取的方法沒(méi)有加鎖 寫(xiě)的時(shí)候才加鎖 所以性能 比 vector高

我們可以從源碼中看出

public E get(int index) {
    return get(getArray(), index);
}
final Object[] getArray() {
    return array;
}
private E get(Object[] a, int index) {
    return (E) a[index];
}

讀操作并沒(méi)有加鎖 這也是效率高的原因

add源碼

寫(xiě)操作加入了 lock鎖

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();
    }
}

(注:新版本jdk1.8后改成了synchronized 因?yàn)樾掳姹緦?duì)synchronized進(jìn)行了升級(jí)提升了效率)

使用示例:

public class ListTest {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 101; i++) {
            new Thread(()->{
                list.add("a");
                System.out.println(list);
            }).start();
        }
    }
}

在這里插入圖片描述

缺點(diǎn):

內(nèi)存問(wèn)題:CopyOnWrite的寫(xiě)復(fù)制機(jī)制,在進(jìn)行寫(xiě)操作的時(shí)候,內(nèi)存里會(huì)同時(shí)駐存在兩個(gè)對(duì)象的內(nèi)存,舊的對(duì)象和新寫(xiě)入的對(duì)象(注意:在復(fù)制的時(shí)候只是復(fù)制容器里的引用,只是在寫(xiě)的時(shí)候會(huì)創(chuàng)建新對(duì) 象添加到新容器里,而舊容器的對(duì)象還在使用,所以有兩份對(duì)象內(nèi)存)。如果這些對(duì)象占用的內(nèi)存比較大,比如說(shuō)100M左右,那么再寫(xiě)入50M數(shù)據(jù)進(jìn)去,內(nèi)存就會(huì)占用150M,那么這個(gè)時(shí)候很有可能造成頻繁的minor GC和major GC。

數(shù)據(jù)一致性問(wèn)題:CopyOnWrite容器只能保證數(shù)據(jù)的最終一致性,不能保證數(shù)據(jù)的實(shí)時(shí)一致性。所以如果你希望寫(xiě)入的的數(shù)據(jù),馬上能讀到,請(qǐng)不要使用CopyOnWrite容器。

到此這篇關(guān)于Java中的CopyOnWriteArrayList詳解的文章就介紹到這了,更多相關(guān)CopyOnWriteArrayList詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Spring boot2.0+配置攔截器攔截靜態(tài)資源的問(wèn)題

    解決Spring boot2.0+配置攔截器攔截靜態(tài)資源的問(wèn)題

    這篇文章主要介紹了解決Spring boot2.0+配置攔截器攔截靜態(tài)資源的問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Java中g(shù)etParameterTypes()方法的使用與原理分析

    Java中g(shù)etParameterTypes()方法的使用與原理分析

    本文詳細(xì)介紹了Java中g(shù)etParameterTypes()方法的使用方式、工作原理及其在實(shí)際開(kāi)發(fā)中的應(yīng)用,該方法用于獲取方法的參數(shù)類(lèi)型列表,并通過(guò)反射機(jī)制在運(yùn)行時(shí)動(dòng)態(tài)地獲取這些信息,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 基于LinkedHashMap實(shí)現(xiàn)LRU緩存

    基于LinkedHashMap實(shí)現(xiàn)LRU緩存

    LinkedHashMap是Java集合中一個(gè)常用的容器,它繼承了HashMap, 是一個(gè)有序的Hash表。那么該如何基于LinkedHashMap實(shí)現(xiàn)一個(gè)LRU緩存呢?本文將介紹LinkedHashMap的實(shí)現(xiàn)原理,感興趣的同學(xué)可以參考一下
    2023-05-05
  • JAVA CyclicBarrier 示例源碼解析

    JAVA CyclicBarrier 示例源碼解析

    CyclicBarrier是一個(gè)強(qiáng)大的同步工具,可以幫助我們實(shí)現(xiàn)復(fù)雜的多線程協(xié)同任務(wù),這篇文章主要介紹了JAVA CyclicBarrier 示例源碼解析,通過(guò)本文,我們深入了解了CyclicBarrier的源碼實(shí)現(xiàn),并通過(guò)一個(gè)簡(jiǎn)單的示例演示了它的用法,需要的朋友可以參考下
    2023-12-12
  • Maven中怎么手動(dòng)添加jar包到本地倉(cāng)庫(kù)詳解(repository)

    Maven中怎么手動(dòng)添加jar包到本地倉(cāng)庫(kù)詳解(repository)

    這篇文章主要給大家介紹了關(guān)于Maven中怎么手動(dòng)添加jar包到本地倉(cāng)庫(kù)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 詳解Java中Checked Exception與Runtime Exception 的區(qū)別

    詳解Java中Checked Exception與Runtime Exception 的區(qū)別

    這篇文章主要介紹了詳解Java中Checked Exception與Runtime Exception 的區(qū)別的相關(guān)資料,這里提供實(shí)例幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • Spring之IOC詳解

    Spring之IOC詳解

    本文主要介紹了Spring中的IOC的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • 詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作

    詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作

    這篇文章主要介紹了詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例分析

    Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例分析

    這篇文章主要介紹了Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • SVN導(dǎo)入maven項(xiàng)目報(bào)錯(cuò)解決方案

    SVN導(dǎo)入maven項(xiàng)目報(bào)錯(cuò)解決方案

    這篇文章主要介紹了SVN導(dǎo)入maven項(xiàng)目報(bào)錯(cuò)解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論