Java中ArrayList同步的2種方法分享
前言:
arrayList 的實(shí)現(xiàn)是默認(rèn)不同步的。這意味著如果一個(gè)線(xiàn)程在結(jié)構(gòu)上修改它并且多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)它,它必須在外部同步。結(jié)構(gòu)修改意味著從列表中添加或刪除元素或顯式調(diào)整后備數(shù)組的大小。改變現(xiàn)有元素的值不是結(jié)構(gòu)修改。
有兩種方法可以創(chuàng)建同步Arraylist:
- 1. Collections.synchronizedList() 方法。
- 2. 使用 CopyOnWriteArrayList。
方法1:使用 Collections.synchronizedList() 方法
要進(jìn)行串行訪(fǎng)問(wèn),必須通過(guò)返回列表完成對(duì)后備列表的所有訪(fǎng)問(wèn)。
在迭代返回的列表時(shí),用戶(hù)必須手動(dòng)同步它。因?yàn)樵趫?zhí)行add()等方法的時(shí)候是加了synchronized關(guān)鍵字的,但是iterator()卻沒(méi)有加。所以在使用的時(shí)候需要加上synchronized。
// Java program to demonstrate working of
// Collections.synchronizedList
import java.util.*;
?
class GFG
{
?? ?public static void main (String[] args)
?? ?{
?? ??? ?List<String> list =
?? ??? ?Collections.synchronizedList(new ArrayList<String>());
?
?? ??? ?list.add("practice");
?? ??? ?list.add("code");
?? ??? ?list.add("quiz");
?
?? ??? ?synchronized(list)
?? ??? ?{
?? ??? ??? ?// must be in synchronized block
?? ??? ??? ?Iterator it = list.iterator();
?
?? ??? ??? ?while (it.hasNext())
?? ??? ??? ??? ?System.out.println(it.next());
?? ??? ?}
?? ?}
}方法 2:使用 CopyOnWriteArrayList
ArrayList 的線(xiàn)程安全變體,其中所有可變操作(例如添加、設(shè)置、刪除...)都是通過(guò)創(chuàng)建底層數(shù)組的單獨(dú)副本來(lái)實(shí)現(xiàn)的。它通過(guò)創(chuàng)建 List 的單獨(dú)副本來(lái)實(shí)現(xiàn)線(xiàn)程安全,這與 vector 或其他集合用于提供線(xiàn)程安全的方式不同。
- 當(dāng)我們不能或不想同步遍歷,但需要防止并發(fā)線(xiàn)程之間的干擾時(shí),它很有用。
- 這是昂貴的,因?yàn)槊看螌?xiě)入操作都涉及單獨(dú)的數(shù)組副本(例如添加,設(shè)置,刪除......)
- 當(dāng)你有List并且需要遍歷它的元素并且不經(jīng)常修改它時(shí),它是非常有效的。
即使在創(chuàng)建迭代器后修改了 copyOnWriteArrayList,迭代器也不會(huì)拋出ConcurrentModificationException,因?yàn)榈髡诘?ArrayList 的單獨(dú)副本,而寫(xiě)操作正在 ArrayList 的另一個(gè)副本上發(fā)生。
// Java program to illustrate the thread-safe ArrayList.
import java.io.*;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
?
class GFG
{
?? ?public static void main (String[] args)
?? ?{
?? ??? ?// creating a thread-safe Arraylist.
?? ??? ?CopyOnWriteArrayList<String> threadSafeList
?? ??? ??? ?= new CopyOnWriteArrayList<String>();
?
?? ??? ?// Adding elements to synchronized ArrayList
?? ??? ?threadSafeList.add("geek");
?? ??? ?threadSafeList.add("code");
?? ??? ?threadSafeList.add("practice");
?
?? ??? ?System.out.println("Elements of synchronized ArrayList :");
?
?? ??? ?// Iterating on the synchronized ArrayList using iterator.
?? ??? ?Iterator<String> it = threadSafeList.iterator();
?
?? ??? ?while (it.hasNext())
?? ??? ??? ?System.out.println(it.next());
?? ?}
}如果我們嘗試通過(guò)迭代器自己的方法修改 CopyOnWriteArrayList 會(huì)發(fā)生什么?
如果您嘗試通過(guò)迭代器自己的方法(例如 add()、set()、remove())修改CopyOnWriteArrayList,它會(huì)拋出 UnsupportedOperationException 。
// Java program to illustrate the thread-safe ArrayList
import java.io.*;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
?
class GFG
{
?? ?public static void main (String[] args)
?? ?{
?? ??? ?// creating a thread-safe Arraylist.
?? ??? ?CopyOnWriteArrayList<String> threadSafeList =
?? ??? ??? ?new CopyOnWriteArrayList<String>();
?
?? ??? ?// Adding elements to synchronized ArrayList
?? ??? ?threadSafeList.add("geek");
?? ??? ?threadSafeList.add("code");
?? ??? ?threadSafeList.add("practice");
?
?? ??? ?System.out.println("Elements of synchronized ArrayList :");
?
?? ??? ?// Iterating on the synchronized ArrayList using iterator.
?? ??? ?Iterator<String> it = threadSafeList.iterator();
?
?? ??? ?while (it.hasNext())
?? ??? ?{
?? ??? ??? ?String str = it.next();
?? ??? ??? ?it.remove();
?? ??? ?}
?? ?}
}CopyOnWriteArrayList 的其他構(gòu)造函數(shù):
- 1. CopyOnWriteArrayList(Collection<? extends E> c):創(chuàng)建一個(gè)包含指定集合元素的列表,按照集合迭代器返回的順序。
- 2. CopyOnWriteArrayList(E[] toCopyIn):創(chuàng)建一個(gè)包含給定數(shù)組副本的列表。
向量同步時(shí)為什么要使用arrayList?
- 性能:
Vector是同步和線(xiàn)程安全的,因此,它比ArrayList稍慢。 - 功能: Vector 在每個(gè)單獨(dú)的操作級(jí)別進(jìn)行同步。通常,程序員喜歡同步整個(gè)操作序列。同步單個(gè)操作既不安全又慢。
- Vectors obsolete:向量被認(rèn)為是過(guò)時(shí)的,并且在 java 中被非正式地棄用。此外,vector 對(duì)幾乎從未完成的每個(gè)單獨(dú)操作進(jìn)行同步。大多數(shù)java程序員更喜歡使用
ArrayList,因?yàn)槿绻麄冃枰M(jìn)行同步,他們可能無(wú)論如何都會(huì)顯式地同步arrayList。
以下是 Java 中 ArrayList 和 CopyOnWriteArrayList 類(lèi)之間的顯著差異。
| 數(shù)組列表 | 復(fù)制寫(xiě)入數(shù)組列表 | |
|---|---|---|
| 同步 | ArrayList 不同步。 | CopyOnWriteArrayList 是同步的。 |
| 線(xiàn)程安全 | ArrayList 不是線(xiàn)程安全的。 | CopyOnWriteArrayList 是線(xiàn)程安全的。 |
| 迭代器類(lèi)型 | ArrayList 迭代器是快速失敗的,如果在迭代過(guò)程中發(fā)生并發(fā)修改,則 ArrayList 會(huì)拋出 ConcurrentModificationException。 | CopyOnWriteArrayList 是故障安全的,它在迭代過(guò)程中永遠(yuǎn)不會(huì)拋出 ConcurrentModificationException。其背后的原因是 CopyOnWriteArrayList 每次修改時(shí)都會(huì)創(chuàng)建一個(gè)新的數(shù)組列表。 |
| 刪除操作 | ArrayList 迭代器支持在迭代過(guò)程中移除元素。 | 如果在迭代期間嘗試刪除元素,則 CopyOnWriteArrayList.remove() 方法會(huì)引發(fā)異常。 |
| 表現(xiàn) | ArrayList 更快。 | CopyOnWriteArrayList 比 ArrayList 慢。 |
| 從 Java 版本開(kāi)始 | 1.2 | 1.5 |
到此這篇關(guān)于Java中ArrayList同步的2種方法分享的文章就介紹到這了,更多相關(guān)Java中ArrayList同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器
這篇文章主要介紹了使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
SpringBoot整合spring-retry實(shí)現(xiàn)接口請(qǐng)求重試機(jī)制及注意事項(xiàng)
今天通過(guò)本文給大家介紹我們應(yīng)該如何使用SpringBoot來(lái)整合spring-retry組件實(shí)現(xiàn)重試機(jī)制及注意事項(xiàng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-08-08
關(guān)于動(dòng)態(tài)參數(shù)使用@PathVariable的解析
這篇文章主要介紹了關(guān)于動(dòng)態(tài)參數(shù)使用@PathVariable的解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java項(xiàng)目中大批量數(shù)據(jù)查詢(xún)導(dǎo)致OOM的解決
本文主要介紹了Java項(xiàng)目中大批量數(shù)據(jù)查詢(xún)導(dǎo)致OOM的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
java類(lèi)中serialVersionUID的作用及其使用
這篇文章主要介紹了java類(lèi)中serialVersionUID的作用及其使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
SpringBoot2.x配置多數(shù)據(jù)源方式
這篇文章主要介紹了SpringBoot2.x配置多數(shù)據(jù)源方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
Java中使用Apache POI讀取word文件簡(jiǎn)單示例
這篇文章主要介紹了Java中使用Apache POI讀取word文件簡(jiǎn)單示例,本文著重介紹了一些必要條件,然后給出一個(gè)簡(jiǎn)單讀取示例,需要的朋友可以參考下2015-06-06

