前言
網(wǎng)站設(shè)計制作、成都網(wǎng)站制作,成都做網(wǎng)站公司-創(chuàng)新互聯(lián)已向上1000家企業(yè)提供了,網(wǎng)站設(shè)計,網(wǎng)站制作,網(wǎng)絡(luò)營銷等服務(wù)!設(shè)計與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗(yàn),合理的價格為您打造企業(yè)品質(zhì)網(wǎng)站。
Vector是java.util包中的一個類。 SynchronizedList是java.util.Collections中的一個靜態(tài)內(nèi)部類。
在多線程的場景中可以直接使用Vector類,也可以使用Collections.synchronizedList(List list)方法來返回一個線程安全的List。
那么,到底SynchronizedList和Vector有沒有區(qū)別,為什么java api要提供這兩種線程安全的List的實(shí)現(xiàn)方式呢?
首先,我們知道Vector和Arraylist都是List的子類,他們底層的實(shí)現(xiàn)都是一樣的。所以這里比較如下兩個list1和list2的區(qū)別:
List<String> list = new ArrayList<String>(); List list2 = Collections.synchronizedList(list); Vector<String> list1 = new Vector<String>();
一、比較幾個重要的方法
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ā)現(xiàn)有兩處不同:
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)除了一個使用同步方法,一個使用同步代碼塊之外幾乎無任何區(qū)別。
通過比較其他方法,我們發(fā)現(xiàn),SynchronizedList里面實(shí)現(xiàn)的方法幾乎都是使用同步代碼塊包上List的方法。如果該List是ArrayList,那么,SynchronizedList和Vector的一個比較明顯區(qū)別就是一個使用了同步代碼塊,一個使用了同步方法。
二、區(qū)別分析
數(shù)據(jù)增長區(qū)別
從內(nèi)部實(shí)現(xiàn)機(jī)制來講ArrayList和Vector都是使用數(shù)組(Array)來控制集合中的對象。當(dāng)你向這兩種類型中增加元素的時候,如果元素的數(shù)目超出了內(nèi)部數(shù)組目前的長度它們都需要擴(kuò)展內(nèi)部數(shù)組的長度,Vector缺省情況下自動增長原來一倍的數(shù)組長度,ArrayList是原來的50%,所以最后你獲得的這個集合所占的空間總是比你實(shí)際需要的要大。所以如果你要在集合中保存大量的數(shù)據(jù)那么使用Vector有一些優(yōu)勢,因?yàn)槟憧梢酝ㄟ^設(shè)置集合的初始化大小來避免不必要的資源開銷。
同步代碼塊和同步方法的區(qū)別
因?yàn)镾ynchronizedList只是使用同步代碼塊包裹了ArrayList的方法,而ArrayList和Vector中同名方法的方法體內(nèi)容并無太大差異,所以在鎖定范圍和鎖的作用域上兩者并無卻別。 在鎖定的對象區(qū)別上,SynchronizedList的同步代碼塊鎖定的是mutex對象,Vector鎖定的是this對象。那么mutex對象又是什么呢? 其實(shí)SynchronizedList有一個構(gòu)造函數(shù)可以傳入一個Object,如果在調(diào)用的時候顯示的傳入一個對象,那么鎖定的就是用戶傳入的對象。如果沒有指定,那么鎖定的也是this對象。
所以,SynchronizedList和Vector的區(qū)別目前為止有兩點(diǎn):
但是,凡事都有但是。 SynchronizedList中實(shí)現(xiàn)的類并沒有都使用synchronized同步代碼塊。其中有l(wèi)istIterator和listIterator(int index)并沒有做同步處理。但是Vector卻對該方法加了方法鎖。 所以說,在使用SynchronizedList進(jìn)行遍歷的時候要手動加鎖。
但是,但是之后還有但是。
之前的比較都是基于我們將ArrayList轉(zhuǎn)成SynchronizedList。那么如果我們想把LinkedList變成線程安全的,或者說我想要方便在中間插入和刪除的同步的鏈表,那么我可以將已有的LinkedList直接轉(zhuǎn)成 SynchronizedList,而不用改變他的底層數(shù)據(jù)結(jié)構(gòu)。而這一點(diǎn)是Vector無法做到的,因?yàn)樗牡讓咏Y(jié)構(gòu)就是使用數(shù)組實(shí)現(xiàn)的,這個是無法更改的。
所以,最后,SynchronizedList和Vector最主要的區(qū)別:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
文章標(biāo)題:java中SynchronizedList和Vector的區(qū)別詳解
文章地址:http://bm7419.com/article20/igdico.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、App設(shè)計、軟件開發(fā)、App開發(fā)、用戶體驗(yàn)、網(wǎng)站營銷
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)