同步容器通過synchronized關鍵字修飾容器,保證同一時間內只有乙個執行緒在使用容器,從而使得容器執行緒安全。
允許多執行緒同時使用容器,並且保證執行緒安全。核心:鎖,cas,cow,分段鎖。
vector:stack: stack實現的是先進後出的棧,入棧出棧都使用synchronized
hashtable:
實現map介面,實現的功能和hashmap基本一致(hashtable 不可出現null,hashmap鍵值可以使用null);
hashtable在使用的時候也用synchronized修飾了方法
arraylist、hashmap 不是執行緒安全的。collections提供了同步集合類
list list = collections.
synchronizedlist
(new
arraylist()
);set set = collections.
synchronizedset
(new
hashset()
);
copyonwritearraylist:寫的時候複製容器,新增元素的時候,先複製乙個新的容器。讀寫分離。
讀: 從原來的容器讀寫資料過程:寫:把資料寫入到新的容器。
缺點public
boolean
add(e e)
finally
}
1.記憶體占有問題。2.資料一致性問題:只能保證資料的最終一致性,不能保證資料的實時一致性。
hashmap:是執行緒不安全的,在併發情況下會產生死鎖。hashtable:執行緒安全,代價大,簡單粗暴,get/put所有的操作都是synchronized修飾。相當於給整個hashtable加了一把大鎖。
concurrenthashmap: 可以支援併發的讀寫,支援高併發的檢索和更新。原理:在jdk1.7: 陣列+鍊錶+分段鎖
在jdk1.8: 陣列+鍊錶+紅黑樹
不能使用null作為key或者value
取消segments,採用hashentry儲存資料
1.當乙個位置有多個元素的時候,concurrenthashmap優先採用鍊錶的形式儲存
2.當鍊表的元素個數大於8個,並且陣列的長度小於64時,進行擴容。
3.當鍊表的元素個數大於8個,並且陣列長度大於64時,鍊錶轉為紅黑樹。
1.第一次新增元素:put:—>用hash演算法算出元素存放在陣列的哪個位置初始長度:16
—>如果出現放在同乙個位置的時候,優先採用鍊錶的形式存放
—>在同乙個位置的個數達到8個以上的時候,如果陣列的長度小於64的時候,擴容陣列。
—>陣列的長度大於等於64,會將該節點的鍊錶轉換為紅黑樹。
如果沒有初始化table先呼叫inittable()方法進行初始化過程**:如果沒有hash衝突就直接cas插入。
如果陣列在擴容操作就先進行擴容。
如果存在hash衝突,就加鎖來保證執行緒安全(一種是鍊錶形式,直接遍歷到尾端插入,一種是紅黑樹就按照紅黑樹的結構插入)
最後乙個如果鍊錶的數量大於8,就要先轉換成紅黑樹的結構
如果新增成功,就呼叫addcount()方法統計size,並且檢查是否要擴容
單項佇列:只能向隊尾新增元素,從對頭刪除元素。final v putval
(k key, v value,
boolean onlyifabsent)
elseif(
(fh = f.hash)
== moved)
tab =
helptransfer
(tab, f)
;else
node
pred = e;if(
(e = e.next)
== null)}}
else
if(f instanceof
treebin)}
}}if(bincount !=0)
}}addcount
(1l, bincount)
;return null;
}
雙向佇列:頭和尾都支援元素的入隊和出隊。
放入資料:實現類add(object)
offer(object): 如果佇列可以容納,則返回true,否則返回false,該方法不阻塞當前執行方法的執行緒。
put(e): 把object加入到blockingqueue,如果佇列沒有空間,則呼叫此方法的執行緒被阻塞直到佇列有空間在繼續。
獲取資料:
poll(time); 取走佇列排在首位的元素,如果不能立即取走,則可以等設定的time引數的時間,取不到返回false;
poll(timeout):
take(object):取走隊首的元素,如果隊列為空,當前執行緒阻塞,直到佇列中有新的元素加入。
linkedblockingqueue
final object[
] items;
arrayblockingqueuearrayblockqueuedelayqueue: 元素只能當其指定的延遲時間到了,才能從佇列中獲取該元素,
priorityblockingqueue: 基於優先順序的阻塞佇列。
synchronousqueue: 無緩衝的等待佇列。(只有乙個元素)
新增元素:/** main lock guarding all access */
final reentrantlock lock;
/** condition for waiting takes */
private
final condition notempty;
/** condition for waiting puts */
private
final condition notfull;
public
void
put(e e)
throws interruptedexception
finally
}
併發基礎 11 併發 容器
要實現乙個執行緒安全的佇列有兩個方式 一種是使用阻塞演算法,另一種是使用非阻塞演算法。阻塞演算法 使用阻塞演算法的佇列可以用乙個鎖 入隊和出隊同一把鎖 或兩把鎖 入隊和出隊用不同的鎖 來實現。非阻塞的實現方式則可以使用迴圈cas的方式來實現。concurrentlinkedqueue非阻塞執行緒安全...
併發程式設計9 併發容器
解決併發情況下的容器執行緒安全問題 譬如 vector,hashtable,都是給予同步鎖實現的 concurrent包下的類,大部分都是使用系統底層的實現,類似於native public class test09 latch.countdown for thread t arr try catc...
同步容器與併發容器
同步容器 可以簡單地理解為通過synchronized來實現同步的容器,如果有多個執行緒呼叫同步容器的方法,它們將會序列執行。比如vector,hashtable 早起jdk的一部分 及collections.synchronized 等方法返回的容器。可以通過檢視vector,hashtable等...