Java Collection与ConcurrentModificationException
在遍历Java容器(ArrayList, LinkedList, HashSet, TreeSet, HashMap, HashTable)过程中不允许向该容器中Add/Remove元素, 否则会抛出ConcurrentModificationException
但在Java 1.5版本以来, Java类库就提供了一个并发集合(Concurrent collection) CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap, 这是专门为解决死锁和ConcurrentModificationException问题的. 通过使用并发集合可以避免任何显示的同步.
CopyOnWriteArrayList是ArrayList的一种变体, 通过重新拷贝整个底层数组, 在这个拷贝的数组中实现所有的写操作. 由于内部数组不改动, 因此迭代不需要锁定, 速度也非常快. 但如果大量使用, CopyOnWriteArrayList的性能将大受影响.
Observer:
1 interface SetObserver<E>{ 2 public void added(ObservableSet<E> set, E element); 3 }
1 package com.ai.concurrentTest; 2 3 import java.util.ArrayList; 4 import java.util.HashSet; 5 import java.util.List; 6 7 public class ObservableSet<E> extends HashSet<E> { 8 9 private static final long serialVersionUID = 1L; 10 11 public ObservableSet(){ 12 } 13 14 private final List<SetObserver<E>> observers = new ArrayList<SetObserver<E>>(); 15 16 public void addObserver(SetObserver<E> observer){ 17 synchronized(observers){ 18 observers.add(observer); 19 } 20 } 21 22 public void removeObserver(SetObserver<E> observer){ 23 synchronized(observers){ 24 observers.remove(observer); 25 } 26 } 27 28 private void notifyElementAdded(E element){ 29 synchronized(observers){ 30 for(SetObserver<E> observer: observers){ 31 observer.added(this, element); 32 } 33 } 34 } 35 36 public boolean add(E element){ 37 boolean added = super.add(element); 38 if(added) 39 notifyElementAdded(element); 40 return added; 41 } 42 43 public static void main(String[] args){ 44 ObservableSet<Integer> set = new ObservableSet<Integer>(); 45 set.addObserver(new SetObserver<Integer>() { 46 47 @Override 48 public void added(ObservableSet<Integer> set, Integer element) { 49 System.out.println("Observer 1: "+element); 50 51 } 52 }); 53 set.addObserver(new SetObserver<Integer>() { 54 55 @Override 56 public void added(ObservableSet<Integer> set, Integer element) { 57 System.out.println("Observer 2 and add another observer: "+element); 58 // set.removeObserver(this); 59 set.addObserver(new SetObserver<Integer>() { 60 61 @Override 62 public void added(ObservableSet<Integer> set, 63 Integer element) { 64 System.out.println("This is new observer."); 65 66 } 67 }); 68 } 69 }); 70 71 for(int i=0; i<100; i++){ 72 set.add(i); 73 } 74 } 75 76 77 }