ArrayBlockingQueue
LinkedBlockingQueue
數組是連續的一片內存
鏈表是不連續的一片內存
傳統方式下用Collections工具類提供的synchronizedCollection方法來獲得同步集合。
java5中提供了如下一些同步集合類:
> 通過看java.util.concurrent包下的介紹可以知道有哪些並發集合
> ConcurrentHashMap 可以進行並發操作的HashMap,並發的HashMap還有 Collections.synchronizedMap(m) ,有了ConcurrentHashMap后,Collections.synchronizedMap(m)不怎么使用了。
>ConcurrentSkipListMap 實現了SortedMap<K,V> ,類似於TreeMap
>ConcurrentSkipListSet 實現了SortedSet, 類似於TreeSet
> CopyOnWriteArrayList
> CopyOnWriteArraySet
傳統方式下的Collection在迭代時,不允許對集合進行修改。
使用Iterator對集合進行迭代時不能修改集合
public class CollectionModifyExceptionTest { public static void main(String[] args) { List<String> strs = new ArrayList<>(); strs.add("aaa"); strs.add("bbb"); strs.add("ccc"); Iterator iterator = strs.iterator(); while(iterator.hasNext()){ System.out.println("....."); String value = (String)iterator.next(); if("aaa".equals(value)){ strs.remove(value); }else{ System.out.println(value); } } } }
以上代碼在遍歷集合時,對集合進行修改,會拋出異常
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.java.thread.CollectionModifyExceptionTest.main(CollectionModifyExceptionTest.java:17)
異常拋在這一句
String value = (String)iterator.next();
/** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { // return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();//此處拋異常 } }
然而在將"aaa" 改成"bbb"時,卻沒有拋出異常
因為在遍歷到 bbb 時,cursor為1(0,1,2),將 bbb 移除后size為2 進行下次遍歷是cursor為 2
所以hasNext()返回的為false 就不會進入循環。
要解決這個問題,可以使用 CopyOnWriteArrayList 在寫的時候有一份拷貝,
public static void main(String[] args) { List<String> strs = new CopyOnWriteArrayList(); strs.add("aaa"); strs.add("bbb"); strs.add("ccc"); Iterator iterator = strs.iterator(); while(iterator.hasNext()){ System.out.println("....."); String value = (String)iterator.next(); if("aaa".equals(value)){ strs.remove(value); }else{ System.out.println(value); } } }