JAva同時の集合クラスの不安全問題の深い分析
一、List
public static void listNotSafe(){
List list = new ArrayList<>(); //new ArrayList<>(); new
List list1 = Collections.synchronizedList(new ArrayList<>());
CopyOnWriteArrayList
2.故障現象java.util.ConcurrentModificationException 3.原因を引き起こす
1つのスレッドが書かれていて、もう1つのスレッドが奪い取りに来て、データが一致しない、すなわち同時修正による異常4.ソリューション
読み書きが少ないときはCopeOnWriteArrayListというクラスがおすすめです
書き込み時にコピーし、読み書きを分離するメリット:読み取り操作が完全にロックされていない
使用シーン:書き込み操作が非常に少ない場合、読み書きの短い不一致を許容できます.
CopyOnWriteArrayList反復器は読み取り専用で、追加削除はサポートされていません.
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();
}
}
二、Set
1、コードプレゼンテーション:
public class HashSetNotSafeDemo {
public static void main(String[] args) {
Set list = new HashSet<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
2、解決策:
3、CopyOnWriteArraySet下位ソース:
下位レベルでのCopyOnWriteArrayListの使用
public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList();}
4、HashSet下位ソース
HashSetのkeyはあなたのadd()の値で、valueはPRESENT Objectタイプという定数です.つまりHashSetはkeyだけに関心を持っています.
public HashSet() {
map = new HashMap<>();
}
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
三、Map
1、コードプレゼンテーション:
public class HashMapNotSafeDemo {
public static void main(String[] args) {
Map map = new HashMap<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
System.out.println(map);
}, String.valueOf(i)).start();
}
}
}
2、解決策