同步類容器都是線程安全的,但某些情況下可能需要加鎖來保護符合操作 複合操作:迭代(反覆訪問元素,遍歷完容器中所有的元素);跳轉(根據指定的順序找到當前元素的下一個元素);條件運算 這些複合操作在多線程併發地修改容器時,可能會表現出意外的行為,最經典的便是ConcurrentModificationE ...
- 同步類容器都是線程安全的,但某些情況下可能需要加鎖來保護符合操作
- 複合操作:迭代(反覆訪問元素,遍歷完容器中所有的元素);跳轉(根據指定的順序找到當前元素的下一個元素);條件運算
- 這些複合操作在多線程併發地修改容器時,可能會表現出意外的行為,最經典的便是ConcurrentModificationException,原因是當容器迭代的過程中,被併發的修改了內容,這是由於早期迭代器設計的時候並沒有考慮併發修改的問
異常代碼及解決方法
1 package com.bfxy.thread.cord.collection; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.Iterator; 7 import java.util.List; 8 import java.util.Vector; 9 import java.util.concurrent.ConcurrentHashMap; 10 11 public class UseSyncCollection { 12 13 // 出現java.util.ConcurrentModificationException 增強for迴圈是多線程 不允許遍歷時修改容器的元素 14 public Collection<String> m1(Vector<String> list) { 15 for (String temp : list) { 16 if ("3".equals(temp)) { 17 list.remove(temp); 18 } 19 } 20 return list; 21 22 } 23 // 出現java.util.ConcurrentModificationException iterator是多線程 不允許遍歷時修改容器內元素 24 public Collection<String> m2(Vector<String> list) { 25 Iterator<String> iterator = list.iterator(); 26 while (iterator.hasNext()) { 27 String temp = iterator.next(); 28 if ("3".equals(temp)) { 29 list.remove(temp); 30 } 31 } 32 return list; 33 34 } 35 //successful! 單線程 36 public Collection<String> m3(Vector<String> list) { 37 for (int i = 0; i < list.size(); i++) { 38 if ("3".equals(list.get(i))) { 39 list.remove(i); 40 } 41 } 42 return list; 43 } 44 45 46 public static void main(String[] args) { 47 48 Vector v = new Vector<>(); 49 v.add("1"); 50 v.add("2"); 51 v.add("3"); 52 UseSyncCollection test = new UseSyncCollection(); 53 Collection<String> ret1 = test.m1(v); 54 System.err.println(ret1.toString()); 55 56 // Collection<String> ret2 = test.m2(v); 57 // System.err.println(ret2.toString()); 58 59 // Collection<String> ret3 = test.m3(v); 60 // System.err.println(ret3.toString()); 61 62 63 // List<String> list = new ArrayList<>(); 64 // Collections.synchronizedCollection(list); 65 66 } 67 }