copyonwritearraylist:jdk1.5新增的執行緒安全的arraylist實現。
[b]使用場景:讀取頻繁,寫較少。
理由:底層的安全性 本質上是依賴於執行緒讀取的資料副本來實現的。因此每次寫都是要複製底層陣列資料的,如果寫頻繁勢必會造成大量的效能消耗。
如果寫非常頻繁,那麼可以根據實際情況選擇:vector 或者collections.synchronizedlist獲取同步保證。[/b]
1、底層的支援資料介面是陣列,volatile 限制了array物件的可見性。
private volatile transient object array;
2、查詢類函式的執行緒安全保證。由於查詢,本質上是是不會變動list的底層資料結構的,也就可以認為查詢類的操作,不需要加鎖,但是這樣[b]不能保證其他的寫操作不會變動底層陣列[/b]。因此不需要加鎖的另外乙個前提是:[b]獲取到的底層陣列是不可變的[/b]。如果陣列可變,比如刪除乙個物件或者清空就可以導致indexoutoffexception,這樣多個執行緒都共享了底層的array資料,自然不是執行緒安全的。
特別**:
/**getarray()返回的引用是事實上不可變的,如果沒有這個保證,那麼這個操作不可能是執行緒安全
*/public int size()
/**有和size方法同樣的先決條件
*/public boolean contains(object o)
//同上
public int indexof(object o)
3、底層資料返回類的執行緒安全保證。典型的的是toarray方法,由於toarray方法返回的陣列時原始陣列的copy,所以是安全的執行緒發布。也即當前物件的toarray 方法在任何執行緒中返回的物件都是執行緒內封閉,自然是安全的。此方法的另外乙個先決條件:返回的elements是事實不可變的。
public object toarray()
4、修改底層陣列的操作。
/**變更底層陣列的操作
*/public e set(int index, e element) else
return (e)oldvalue;
} finally
}/**
刪除乙個元素的執行緒安全保證
*/public e remove(int index)
return (e)oldvalue;
} finally
}//結合以上分析,很容易分析出此操作的執行緒安全性!
public boolean addifabsent(e e)
newelements[len] = e;
setarray(newelements);
return true;
} finally
}
5、迭代器 的安全性分析。
public listiteratorlistiterator()
private static class cowiteratorimplements listiterator
....
}
總結:copyonwritearraylist 的安全性保證:
1、寫執行緒的操作加鎖(保證多個寫執行緒不會有操作被覆蓋)
2、寫執行緒操作的底層陣列複製(保證執行緒讀取操作不會在其他執行緒寫操作前後發生執行緒不安全的操作)
3、獲取底層陣列時的 底層陣列的複製(保證返回的底層資料不在多個執行緒中共享,含義與2一致)。
以上是我的理解,有理解錯誤點,請指出!
原始碼剖析 Hashtable 原始碼剖析
hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...
STL之deque原始碼剖析
deque是一種那個雙向開口的連續線性空間,其頭尾端做元素的插入和刪除效率比vector效率高很多。deque和vector的最大差異,一在於deque允許常數時間內對頭尾端進行元素插入或移除操作,二在於deque沒有所謂容量概念,因為它是動態地分段連續空間組合而成,隨時可以增加一段新的空間並鏈結起...
LevelDB原始碼剖析之Memtable 1
memtable是leveldb很重要的一塊,leveldb的核心之一。我們肯定關注kv資料在memtable中是如何組織的,秘密在skip list中。在leveldb中,所有記憶體中的kv資料都儲存在memtable中,物理disk則儲存在sstable中。在系統執行過程中,如果memtable...