集合的線程安全性問題

請問ArrayList,HashSet,HashMap是線程安全的嗎?如果不是我想要線程安全的集合怎麼辦呢?

在集合中Vector 和HashTable是線程安全的,打開源碼發現其實就是把各自核心方法添加了synchornized關鍵字。

List<String> list = new ArrayList<>();//線程不安全 

方法1:

List<String> list = new Vector<>();

方法2:

List<String> list = Collections.synchronizedList(new ArrayList<>());

 

方法3:

List<String> list = new CopyOnWriteArrayList<>();//寫時複製技術

Set<String> set = new CopyOnWriteArraySet<>(); 

Map<String,String> map = new ConcurrentHashMap<>(); 

package cn.zh.juc1205;
/**
 * 1.故障現象
 * Java.util.ConcurrentModificationException
 * 2.導致原因
 *
 * 3.解決方法
 *      3.1 new Vector<>()
 *      3.2 Collections.synchronizedList(new ArrayList<>))
 *      3.3 new CopyOnWriteArrayList()
 * 4.優化建議(同樣的錯誤不犯第二次)
 *
 */

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

public class NotSafeDemo03 {

    public static void main(String[] args) {

        Map<String,String> map = new ConcurrentHashMap<>();
        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();
        }
    }

    public static void setNotSage(String[] args) {

        Set<String> set = new CopyOnWriteArraySet<>();
        for (int i = 1; i <= 30;i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(set);
            },String.valueOf(i)).start();
        }

    }

    public static void listNodtSafe() {
        //        List<String> list = new ArrayList<>();
//        List<String> list = new Vector<>();
//        List<String> list = Collections.synchronizedList(new ArrayList<>());
        //寫時複製技術
        List<String> list = new CopyOnWriteArrayList<>();
        /*list.add("a");
        list.add("b");
        list.add("c");
        list.forEach(System.out::println);//方法引用*/
        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();
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章