您好,登錄后才能下訂單哦!
本篇內容主要講解“java中SynchronizedList和Vector的區別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“java中SynchronizedList和Vector的區別”吧!
前言
Vector是java.util包中的一個類。 SynchronizedList是java.util.Collections中的一個靜態內部類。
在多線程的場景中可以直接使用Vector類,也可以使用Collections.synchronizedList(List list)方法來返回一個線程安全的List。
那么,到底SynchronizedList和Vector有沒有區別,為什么java api要提供這兩種線程安全的List的實現方式呢?
首先,我們知道Vector和Arraylist都是List的子類,他們底層的實現都是一樣的。所以這里比較如下兩個list1和list2的區別:
List<String> list = new ArrayList<String>();List list2 = Collections.synchronizedList(list);Vector<String> list1 = new Vector<String>();
一、比較幾個重要的方法
1.1 add方法
Vector的實現:
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 codeif (minCapacity - elementData.length > 0)grow(minCapacity);}
synchronizedList的實現:
public void add(int index, E element) {synchronized (mutex) {list.add(index, element);}}
這里,使用同步代碼塊的方式調用ArrayList的add()方法。ArrayList的add方法內容如下:
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);}
從上面兩段代碼中發現有兩處不同:
Vector使用同步方法實現,synchronizedList使用同步代碼塊實現。 兩者的擴充數組容量方式不一樣(兩者的add方法在擴容方面的差別也就是ArrayList和Vector的差別。)
1.2 remove方法
synchronizedList的實現:
public E remove(int index) {synchronized (mutex) {return list.remove(index);}}
ArrayList類的remove方法內容如下:
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 workreturn oldValue;}
Vector的實現:
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 workreturn oldValue;}
從remove方法中我們發現除了一個使用同步方法,一個使用同步代碼塊之外幾乎無任何區別。
通過比較其他方法,我們發現,SynchronizedList里面實現的方法幾乎都是使用同步代碼塊包上List的方法。如果該List是ArrayList,那么,SynchronizedList和Vector的一個比較明顯區別就是一個使用了同步代碼塊,一個使用了同步方法。
二、區別分析
數據增長區別
從內部實現機制來講ArrayList和Vector都是使用數組(Array)來控制集合中的對象。當你向這兩種類型中增加元素的時候,如果元素的數目超出了內部數組目前的長度它們都需要擴展內部數組的長度,Vector缺省情況下自動增長原來一倍的數組長度,ArrayList是原來的50%,所以最后你獲得的這個集合所占的空間總是比你實際需要的要大。所以如果你要在集合中保存大量的數據那么使用Vector有一些優勢,因為你可以通過設置集合的初始化大小來避免不必要的資源開銷。
同步代碼塊和同步方法的區別
同步代碼塊在鎖定的范圍上可能比同步方法要小,一般來說鎖的范圍大小和性能是成反比的。 同步塊可以更加精確的控制鎖的作用域(鎖的作用域就是從鎖被獲取到其被釋放的時間),同步方法的鎖的作用域就是整個方法。 靜態代碼塊可以選擇對哪個對象加鎖,但是靜態方法只能給this對象加鎖。
因為SynchronizedList只是使用同步代碼塊包裹了ArrayList的方法,而ArrayList和Vector中同名方法的方法體內容并無太大差異,所以在鎖定范圍和鎖的作用域上兩者并無卻別。 在鎖定的對象區別上,SynchronizedList的同步代碼塊鎖定的是mutex對象,Vector鎖定的是this對象。那么mutex對象又是什么呢? 其實SynchronizedList有一個構造函數可以傳入一個Object,如果在調用的時候顯示的傳入一個對象,那么鎖定的就是用戶傳入的對象。如果沒有指定,那么鎖定的也是this對象。
所以,SynchronizedList和Vector的區別目前為止有兩點:
如果使用add方法,那么他們的擴容機制不一樣。 SynchronizedList可以指定鎖定的對象。
但是,凡事都有但是。 SynchronizedList中實現的類并沒有都使用synchronized同步代碼塊。其中有listIterator和listIterator(int index)并沒有做同步處理。但是Vector卻對該方法加了方法鎖。 所以說,在使用SynchronizedList進行遍歷的時候要手動加鎖。
但是,但是之后還有但是。
之前的比較都是基于我們將ArrayList轉成SynchronizedList。那么如果我們想把LinkedList變成線程安全的,或者說我想要方便在中間插入和刪除的同步的鏈表,那么我可以將已有的LinkedList直接轉成 SynchronizedList,而不用改變他的底層數據結構。而這一點是Vector無法做到的,因為他的底層結構就是使用數組實現的,這個是無法更改的。
所以,最后,SynchronizedList和Vector最主要的區別:
SynchronizedList有很好的擴展和兼容功能。他可以將所有的List的子類轉成線程安全的類。 使用SynchronizedList的時候,進行遍歷時要手動進行同步處理。 SynchronizedList可以指定鎖定的對象。
到此,相信大家對“java中SynchronizedList和Vector的區別”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。