Java并發(fā)J.U.C并發(fā)容器類list set queue
1. List
ArrayList
- 本質(zhì)就是一個數(shù)組
- 初識化大小默認為 10
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
- 每次擴容后大小變?yōu)樵笮〉?.5倍
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 擴容為1.5倍大小
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}- 使用
for(Object o : list)迭代器進行迭代循環(huán)的時候不應(yīng)該對列表list進行新增或者刪除操作,否則會報ConcurrentModificationException異常,原因是因為迭代過程中會檢查變量數(shù)量和期望的數(shù)量是否一致。
如以下操作就會報錯
int i=0;
for (Object o : list) {
if(i==0) list.add("neco");
i++;
}
拋出異常的代碼
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}LinkedList
- 本質(zhì)就是一個鏈表,沒有什么特殊的內(nèi)容
- 里邊的Node<E>是支持雙向鏈表的
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}CopyOnWriteArrayList
- 在寫的時候復(fù)制了一份出來,然后重新寫入數(shù)據(jù)
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (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();
}
}- 確保了讀寫可以同步進行,但是可能會有臟讀的情況
- 在多讀少寫的情況下可以使用
CopyOnWriteArrayList容器即寫時復(fù)制的容器。
和ArrayList比較,優(yōu)點是并發(fā)安全,缺點有兩個:
1、多了內(nèi)存占用:寫數(shù)據(jù)是copy一份完整的數(shù)據(jù),單獨進行操作。占用雙份內(nèi)存。
2、數(shù)據(jù)一致性:數(shù)據(jù)寫完之后,其他線程不一定是馬上讀取到最新內(nèi)容。

CopyOnWriteArrayList
2. Set 集合
和List比較:不會重復(fù)
| 實現(xiàn) | 原理 | 特點 |
|---|---|---|
| HashSet | 基于HashMap實現(xiàn) | 非線程安全 |
| CopyOnWriteArraySet | 基于CopyOnWriteArrayList | 線程安全 |
| TreeSet | 基于TreeMap | 線程安全,有序,查詢快 |
HashSet
內(nèi)部的實現(xiàn)本質(zhì)就是一個Map(因為key值不重復(fù)),但是只是使用了Key,對于value無所謂
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();CopyOnWriteArraySet
內(nèi)部的本質(zhì)是一個 CopyOnWriteArrayList,通過判斷是否存在來確定是否放入數(shù)據(jù)
/**
* Creates an empty set.
*/
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* the set contains no element {@code e2} such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return al.addIfAbsent(e);
}
/**
* Appends the element, if not present.
*
* @param e element to be added to this list, if absent
* @return {@code true} if the element was added
*/
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
/**
* A version of addIfAbsent using the strong hint that given
* recent snapshot does not contain e.
*/
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {
// Optimize for lost race to another addXXX operation
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}TreeSet
本質(zhì)是一個TreeMap,但是也只用到了Key值,Value值沒有什么意義。
/**
* Constructs a new, empty tree set, sorted according to the
* natural ordering of its elements. All elements inserted into
* the set must implement the {@link Comparable} interface.
* Furthermore, all such elements must be <i>mutually
* comparable</i>: {@code e1.compareTo(e2)} must not throw a
* {@code ClassCastException} for any elements {@code e1} and
* {@code e2} in the set. If the user attempts to add an element
* to the set that violates this constraint (for example, the user
* attempts to add a string element to a set whose elements are
* integers), the {@code add} call will throw a
* {@code ClassCastException}.
*/
public TreeSet() {
this(new TreeMap<E,Object>());
}
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* the set contains no element {@code e2} such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
* @throws ClassCastException if the specified object cannot be compared
* with the elements currently in this set
* @throws NullPointerException if the specified element is null
* and this set uses natural ordering, or its comparator
* does not permit null elements
*/
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();SET接口沒有所謂的有序還是無序。 TreeSet是有序的,此有序是說讀取數(shù)據(jù)的順序和插入數(shù)據(jù)的順序一樣。
HashSet無序? 此無序說的是讀取數(shù)據(jù)的順序不一定和插入數(shù)據(jù)的順序一樣。
3. Queue
Queue API
Queue -隊列數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)。分為阻塞隊列和非阻塞隊列。下列的藍色區(qū)塊,為阻塞隊列特有的方法。

Queue API
阻塞是通過condition來實現(xiàn)的,可參考 Java并發(fā) - Lock接口
- ArrayBlockingQueue 阻塞
- LinkedBlockingQueue 阻塞
- ArrayQueue 非阻塞
- LinkedQueue 非阻塞
以上就是Java并發(fā) - J.U.C并發(fā)容器類 list、set、queue的詳細內(nèi)容,更多關(guān)于Java J.U.C并發(fā)容器類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入理解Java基礎(chǔ)之try-with-resource語法糖
這篇文章主要介紹了深入理解Java基礎(chǔ)之try-with-resource語法糖,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02
Java 客戶端向服務(wù)端上傳mp3文件數(shù)據(jù)的實例代碼
這篇文章主要介紹了Java 客戶端向服務(wù)端上傳mp3文件數(shù)據(jù)的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09
Java整型數(shù)與網(wǎng)絡(luò)字節(jié)序byte[]數(shù)組轉(zhuǎn)換關(guān)系詳解
這篇文章主要介紹了Java整型數(shù)與網(wǎng)絡(luò)字節(jié)序byte[]數(shù)組轉(zhuǎn)換關(guān)系,結(jié)合實例形式歸納整理了java整型數(shù)和網(wǎng)絡(luò)字節(jié)序的byte[]之間轉(zhuǎn)換的各種情況,需要的朋友可以參考下2017-08-08
Java實現(xiàn)4種微信搶紅包算法(小結(jié))
微信紅包是大家經(jīng)常使用的,到現(xiàn)在為止仍然有很多紅包開發(fā)的需求,實現(xiàn)搶紅包算法也是面試常考題,本文就詳細的來介紹一下如何實現(xiàn),感興趣的可以了解一下2021-12-12
java讀取文件:char的ASCII碼值=65279,顯示是一個空字符的解決
這篇文章主要介紹了java讀取文件:char的ASCII碼值=65279,顯示是一個空字符的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
SpringBoot和前端聯(lián)動實現(xiàn)存儲瀏覽記錄功能
這篇文章主要介紹了SpringBoot和前端聯(lián)動實現(xiàn)存儲瀏覽記錄功能,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01

