最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的CopyOnWriteArrayList操作詳解

 更新時間:2023年12月21日 08:46:01   作者:weixin_33979363  
這篇文章主要介紹了Java的CopyOnWriteArrayList操作詳解,  CopyOnWriteArrayList是ArrayList 的一個線程安全的變體,其中所有可變操作(add、set等等)都是通過對底層數(shù)組進行一次新的復(fù)制來實現(xiàn)的,需要的朋友可以參考下

CopyOnWriteArrayList

CopyOnWriteArrayList是ArrayList 的一個線程安全的變體,其中所有可變操作(add、set等等)都是通過對底層數(shù)組進行一次新的復(fù)制來實現(xiàn)的。

這一般需要很大的開銷,但是當(dāng)遍歷操作的數(shù)量大大超過可變操作的數(shù)量時,這種方法可能比其他替代方法更 有效。在不能或不想進行同步遍歷,但又需要從并發(fā)線程中排除沖突時,它也很有用。“快照”風(fēng)格的迭代器方法在創(chuàng)建迭代器時使用了對數(shù)組狀態(tài)的引用。此數(shù)組在迭代器的生存期內(nèi)不會更改,因此不可能發(fā)生沖突,并且迭代器保證不會拋出ConcurrentModificationException。創(chuàng)建迭代器以后,迭代器就不會反映列表的添加、移除或者更改。在迭代器上進行的元素更改操作(remove、set和add)不受支持。這些方法將拋出UnsupportedOperationException。允許使用所有元素,包括null。

內(nèi)存一致性效果:當(dāng)存在其他并發(fā) collection 時,將對象放入CopyOnWriteArrayList之前的線程中的操作 happen-before 隨后通過另一線程從CopyOnWriteArrayList中訪問或移除該元素的操作。

這種情況一般在多線程操作時,一個線程對list進行修改。一個線程對list進行fore時會出現(xiàn)java.util.ConcurrentModificationException錯誤。

下面來看一個列子:兩個線程一個線程fore一個線程修改list的值。

package com.lucky.concurrent.list;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CopyOnWriteArrayListDemo {
	/**
	 * 讀線程
	 * @author wangjie
	 *
	 */
	private static class ReadTask implements Runnable {
		List<String> list;
		public ReadTask(List<String> list) {
			this.list = list;
		}
		public void run() {
			for (String str : list) {
				System.out.println(str);
			}
		}
	}
	/**
	 * 寫線程
	 * @author wangjie
	 *
	 */
	private static class WriteTask implements Runnable {
		List<String> list;
		int index;
		public WriteTask(List<String> list, int index) {
			this.list = list;
			this.index = index;
		}
		public void run() {
			list.remove(index);
			list.add(index, "write_" + index);
		}
	}
	public void run() {
		final int NUM = 10;
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < NUM; i++) {
			list.add("main_" + i);
		}
		ExecutorService executorService = Executors.newFixedThreadPool(NUM);
		for (int i = 0; i < NUM; i++) {
			executorService.execute(new ReadTask(list));
			executorService.execute(new WriteTask(list, i));
		}
		executorService.shutdown();
	}
	public static void main(String[] args) {
		new CopyOnWriteArrayListDemo().run();
	}
}

從結(jié)果中可以看出來。在多線程情況下報錯。其原因就是多線程操作結(jié)果:那這個種方案不行我們就換個方案。

用jdk自帶的類CopyOnWriteArrayList來做容器。

這個類和ArrayList最大的區(qū)別就是add(E) 的時候。容器會自動copy一份出來然后再尾部add(E)。

看源碼:

/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#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();
	}
    }

用到了Arrays.copyOf 方法。這樣導(dǎo)致每次操作的都不是同一個引用。也就不會出現(xiàn)java.util.ConcurrentModificationException錯誤。

換了種方案看代碼:

//		List<String> list = new ArrayList<String>();
		CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();

也就把容器list換成了 CopyOnWriteArrayList,其他的沒變。

線程里面的list不用改。因為 CopyOnWriteArrayList實現(xiàn)的也是list<E> 接口。

其結(jié)果沒報錯。 CopyOnWriteArrayList add(E) 和remove(int index)都是對新的數(shù)組進行修改和新增。

所以在多線程操作時不會出現(xiàn)java.util.ConcurrentModificationException錯誤。

所以最后得出結(jié)論:CopyOnWriteArrayList適合使用在讀操作遠遠大于寫操作的場景里,比如緩存。

發(fā)生修改時候做copy,新老版本分離,保證讀的高性能,適用于以讀為主的情況。

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

相關(guān)文章

  • idea不自動生成target問題及解決

    idea不自動生成target問題及解決

    文章講述了在使用IDEA開發(fā)Maven項目時遇到的常見問題及其解決方法,主要包括項目導(dǎo)入問題、資源文件未打包問題以及清理緩存的技巧
    2026-03-03
  • SpringBoot2自動裝配原理解析

    SpringBoot2自動裝配原理解析

    這篇文章主要介紹了SpringBoot2自動裝配原理解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Mybatis步驟分解實現(xiàn)一個增刪改查程序

    Mybatis步驟分解實現(xiàn)一個增刪改查程序

    MybatisPlus是國產(chǎn)的第三方插件, 它封裝了許多常用的CURDapi,免去了我們寫mapper.xml的重復(fù)勞動。本文將整合MybatisPlus實現(xiàn)增刪改查功能,感興趣的可以了解一下
    2022-05-05
  • Java FTPClient實現(xiàn)文件上傳下載

    Java FTPClient實現(xiàn)文件上傳下載

    這篇文章主要為大家詳細介紹了Java FTPClient實現(xiàn)文件上傳下載的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • java之Object類用法實例

    java之Object類用法實例

    這篇文章主要介紹了java之Object類用法實例,是Java程序設(shè)計中比較重要的概念,以實例的形式對其定義及用法做了較為深入的講解,需要的朋友可以參考下
    2014-10-10
  • java8中定時任務(wù)最佳實現(xiàn)方式(實現(xiàn)原理)

    java8中定時任務(wù)最佳實現(xiàn)方式(實現(xiàn)原理)

    這篇文章主要介紹了java8中定時任務(wù)最佳實現(xiàn)方式,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-12-12
  • 普通類注入不進spring bean的解決方法

    普通類注入不進spring bean的解決方法

    這篇文章主要介紹了普通類注入不進spring bean的解決方法,幫助大家更好的理解和使用spring bean,感興趣的朋友可以了解下
    2021-01-01
  • Mybatis-Plus select不去查全部字段和去重問題

    Mybatis-Plus select不去查全部字段和去重問題

    本文介紹了MyBatis-Plus中查詢指定字段的方法和查詢分組查詢的方法,還介紹了使用`queryWrapper`的的`select()`方法來指定查詢的字段,并并并并提供了查詢?nèi)ブ?IN操作和特殊字符轉(zhuǎn)義的示例代碼
    2026-04-04
  • Java實現(xiàn)的連續(xù)奇數(shù)(n+2*x)是合數(shù)的算法題暴力算法

    Java實現(xiàn)的連續(xù)奇數(shù)(n+2*x)是合數(shù)的算法題暴力算法

    這篇文章主要介紹了Java實現(xiàn)的連續(xù)奇數(shù)(n+2*x)是合數(shù)的算法題暴力算法,本文包含運算結(jié)果和實現(xiàn)代碼,需要的朋友可以參考下
    2014-09-09
  • java單機滑動窗口限流器的實現(xiàn)

    java單機滑動窗口限流器的實現(xiàn)

    本文主要介紹了java單機滑動窗口限流器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03

最新評論

福泉市| 平顶山市| 自贡市| 洪湖市| 通道| 四平市| 惠州市| 米易县| 布拖县| 彰化县| 双江| 瓦房店市| 绥棱县| 明溪县| 包头市| 突泉县| 镶黄旗| 天峻县| 防城港市| 新田县| 洛宁县| 如东县| 健康| 兴文县| 十堰市| 灌南县| 临夏县| 五莲县| 建昌县| 西宁市| 大埔县| 泰宁县| 探索| 利津县| 民乐县| 揭东县| 湖口县| 都江堰市| 郸城县| 富顺县| 伊通|