併發程式設計(一)——同步類容器

Broke、薪雪發表於2018-12-26
  • 同步類容器都是執行緒安全的,但某些情況下可能需要加鎖來保護符合操作
  • 複合操作:迭代(反覆訪問元素,遍歷完容器中所有的元素);跳轉(根據指定的順序找到當前元素的下一個元素);條件運算
  • 這些複合操作在多執行緒併發地修改容器時,可能會表現出意外的行為,最經典的便是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 }

 

        

相關文章