java8 關於Set集合的線程安全使用


場景:並發多線程,往Set集合中存放數據時,發現最終的數量結果不對,經過排查,沒有使用線程安全的Set導致

 

哈哈,不會描述,代碼解釋一切,下面代碼,使用的 Sets.newHashSet() 和 Collections.synchronizedSet(Sets.newHashSet()) 兩種方式,來聲明一個Set集合,其中第一個不是線程安全,第二個是線程安全

代碼:

 public static void main(String[] args) {
        ExecutorService executor = new ThreadPoolExecutor(
                10, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100000), threadFactory);

        //放入0-69999數字的字符串,沒有重復的
        List<String> numList = Lists.newArrayList();
        for (int i = 0; i < 70000; i++) {
            numList.add(String.valueOf(i));
        }

        //將集合按2000一組分隔
        List<List<String>> tmpNumList = ToolsUtil.spliceArrays(numList, 2000);

        //多線程運行
        List<Future<Integer>> futureList = new ArrayList<>();
        Set<String> numSet = Sets.newHashSet();
        Set<String> numSyncSet = Collections.synchronizedSet(Sets.newHashSet());
        tmpNumList.forEach(list -> futureList.add(executor.submit(() -> {
            list.forEach(num -> {
                numSet.add(num);
                numSyncSet.add(num);
            });
            return 1;
        })));

        futureList.forEach(future -> {
            try {
                future.get();
            } catch (Exception e) {
                logger.warn("error,", e);
            }
        });

        //結果輸出
        System.out.println("線程不安全的Set:" + numSet.size());
        System.out.println("線程安全的Set:" + numSyncSet.size());
    }

控制台輸出:(運行多次,線程不安全的數字一直變動,且不正確)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM