網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
?Vector是java.util包中的一個(gè)類。 SynchronizedList是java.util.Collections中的一個(gè)靜態(tài)內(nèi)部類。
在多線程的場(chǎng)景中可以直接使用Vector類,也可以使用Collections.synchronizedList(List?list)方法來(lái)返回一個(gè)線程安全的List。
那么,到底SynchronizedList和Vector有沒(méi)有區(qū)別,為什么java api要提供這兩種線程安全的List的實(shí)現(xiàn)方式呢?
首先,我們知道Vector和Arraylist都是List的子類,他們底層的實(shí)現(xiàn)都是一樣的。所以這里比較如下兩個(gè)list1
和list2
的區(qū)別:
List<String> list = new ArrayList<String>();
List list2 = Collections.synchronizedList(list);
Vector<String> list1 = new Vector<String>();
一 比較重要的幾個(gè)方法
?1.1 add方法
Vector的實(shí)現(xiàn):
public void add(int index, E element) {
insertElementAt(element, index);
}
public synchronized void insertElementAt(E obj, int index) {
modCount++;
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
elementData[index] = obj;
elementCount++;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
synchronizedList的實(shí)現(xiàn):
public void add(int index, E element) {
synchronized (mutex) {
list.add(index, element);
}
}
這里,使用同步代碼塊的方式調(diào)用ArrayList的add()方法。ArrayList的add方法內(nèi)容如下:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
復(fù)制ErrorOK!
從上面兩段代碼中發(fā)現(xiàn)有兩處不同:?1.Vector使用同步方法實(shí)現(xiàn),synchronizedList使用同步代碼塊實(shí)現(xiàn)。 2.兩者的擴(kuò)充數(shù)組容量方式不一樣(兩者的add方法在擴(kuò)容方面的差別也就是ArrayList和Vector的差別。)
1.2 remove方法
synchronizedList的實(shí)現(xiàn):
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
ArrayList類的remove方法內(nèi)容如下:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
Vector的實(shí)現(xiàn):
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work
return oldValue;
}
從remove方法中我們發(fā)現(xiàn)除了一個(gè)使用同步方法,一個(gè)使用同步代碼塊之外幾乎無(wú)任何區(qū)別。
通過(guò)比較其他方法,我們發(fā)現(xiàn),SynchronizedList里面實(shí)現(xiàn)的方法幾乎都是使用同步代碼塊包上List的方法。如果該List是ArrayList,那么,SynchronizedList和Vector的一個(gè)比較明顯區(qū)別就是一個(gè)使用了同步代碼塊,一個(gè)使用了同步方法。
三 區(qū)別分析?
數(shù)據(jù)增長(zhǎng)區(qū)別
從內(nèi)部實(shí)現(xiàn)機(jī)制來(lái)講ArrayList和Vector都是使用數(shù)組(Array)來(lái)控制集合中的對(duì)象。當(dāng)你向這兩種類型中增加元素的時(shí)候,如果元素的數(shù)目超出了內(nèi)部數(shù)組目前的長(zhǎng)度它們都需要擴(kuò)展內(nèi)部數(shù)組的長(zhǎng)度,Vector缺省情況下自動(dòng)增長(zhǎng)原來(lái)一倍的數(shù)組長(zhǎng)度,ArrayList是原來(lái)的50%,所以最后你獲得的這個(gè)集合所占的空間總是比你實(shí)際需要的要大。所以如果你要在集合中保存大量的數(shù)據(jù)那么使用Vector有一些優(yōu)勢(shì),因?yàn)槟憧梢酝ㄟ^(guò)設(shè)置集合的初始化大小來(lái)避免不必要的資源開銷。
同步代碼塊和同步方法的區(qū)別
1.同步代碼塊在鎖定的范圍上可能比同步方法要小,一般來(lái)說(shuō)鎖的范圍大小和性能是成反比的。
2.同步塊可以更加精確的控制鎖的作用域(鎖的作用域就是從鎖被獲取到其被釋放的時(shí)間),同步方法的鎖的作用域就是整個(gè)方法。
3.同步代碼塊可以選擇對(duì)哪個(gè)對(duì)象加鎖,但是靜態(tài)方法只能給this對(duì)象加鎖。
因?yàn)镾ynchronizedList只是使用同步代碼塊包裹了ArrayList的方法,而ArrayList和Vector中同名方法的方法體內(nèi)容并無(wú)太大差異,所以在鎖定范圍和鎖的作用域上兩者并無(wú)區(qū)別。 在鎖定的對(duì)象區(qū)別上,SynchronizedList的同步代碼塊鎖定的是mutex對(duì)象,Vector鎖定的是this對(duì)象。那么mutex對(duì)象又是什么呢? 其實(shí)SynchronizedList有一個(gè)構(gòu)造函數(shù)可以傳入一個(gè)Object,如果在調(diào)用的時(shí)候顯示的傳入一個(gè)對(duì)象,那么鎖定的就是用戶傳入的對(duì)象。如果沒(méi)有指定,那么鎖定的也是this對(duì)象。
所以,SynchronizedList和Vector的區(qū)別目前為止有兩點(diǎn): 1.如果使用add方法,那么他們的擴(kuò)容機(jī)制不一樣。 2.SynchronizedList可以指定鎖定的對(duì)象。
但是,凡事都有但是。 SynchronizedList中實(shí)現(xiàn)的類并沒(méi)有都使用synchronized同步代碼塊。其中有l(wèi)istIterator和listIterator(int index)并沒(méi)有做同步處理。但是Vector卻對(duì)該方法加了方法鎖。 所以說(shuō),在使用SynchronizedList進(jìn)行遍歷的時(shí)候要手動(dòng)加鎖。
但是,但是之后還有但是。
之前的比較都是基于我們將ArrayList轉(zhuǎn)成SynchronizedList。那么如果我們想把LinkedList變成線程安全的,或者說(shuō)我想要方便在中間插入和刪除的同步的鏈表,那么我可以將已有的LinkedList直接轉(zhuǎn)成 SynchronizedList,而不用改變他的底層數(shù)據(jù)結(jié)構(gòu)。而這一點(diǎn)是Vector無(wú)法做到的,因?yàn)樗牡讓咏Y(jié)構(gòu)就是使用數(shù)組實(shí)現(xiàn)的,這個(gè)是無(wú)法更改的。
所以,最后,SynchronizedList和Vector最主要的區(qū)別:?1.SynchronizedList有很好的擴(kuò)展和兼容功能。他可以將所有的List的子類轉(zhuǎn)成線程安全的類。?2.使用SynchronizedList的時(shí)候,進(jìn)行遍歷時(shí)要手動(dòng)進(jìn)行同步處理。?3.SynchronizedList可以指定鎖定的對(duì)象。
原文鏈接:https://blog.csdn.net/weixin_47146097/article/details/126335720
相關(guān)推薦
- 2024-02-25 關(guān)于數(shù)據(jù)庫(kù)時(shí)間為datetime,前臺(tái)數(shù)據(jù)不正常級(jí)時(shí)區(qū)+8問(wèn)題
- 2022-07-07 基于Python制作一個(gè)文件解壓縮工具_(dá)python
- 2022-11-20 Go語(yǔ)言操作Excel利器之excelize類庫(kù)詳解_Golang
- 2022-11-29 C#中泛型容器Stack<T>的用法并實(shí)現(xiàn)”撤銷/重做”功能_C#教程
- 2022-07-14 python如何獲取當(dāng)前系統(tǒng)的日期_python
- 2022-03-15 antd-mobile 請(qǐng)求時(shí)Loading組件
- 2022-08-15 linux環(huán)境下查看日志文件的一些操作
- 2022-10-11 RabbitMQ:生產(chǎn)者消息確認(rèn)、消息持久化、消費(fèi)者消息確認(rèn)、消費(fèi)失敗重試機(jī)制
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支