Java有线程安全的set吗?
生活随笔
收集整理的這篇文章主要介紹了
Java有线程安全的set吗?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今日推薦
Web登錄很簡單?開玩笑!知乎熱問:國家何時整治程序員的高薪現象?太可怕了!注解+反射優雅的實現Excel導入導出(通用版)Fluent Mybatis 牛逼!Nginx 常用配置清單這玩意比ThreadLocal叼多了,嚇得我趕緊分享出來。來源:blog.csdn.net/li_canhui/article/details/91393247
在多線程環境下,要使用線程安全的集合,比如,ConcurrentHashMap是線程安全的HashMap,CopyOnWriteArrayList是線程安全的ArrayList。那么HashSet對應的線程安全集合,是什么呢?java有沒有提供默認實現呢?
在java的concurrent包中,我找到了CopyOnWriteArraySet,那么它是線程安全的嗎?下面是測試代碼。
public?static?void?main(String[]?args)?{Set<String>?set?=?new?CopyOnWriteArraySet<>();ExecutorService?service?=?Executors.newFixedThreadPool(12);int?times?=?10000;AtomicInteger?flag?=?new?AtomicInteger(0);for(int?i?=?0;?i?<?times;?i?++){service.execute(()->{set.add("a"?+?flag.getAndAdd(1));});}service.shutdown();try?{service.awaitTermination(Long.MAX_VALUE,?TimeUnit.DAYS);}catch?(Exception?e){e.printStackTrace();}System.out.println(set.size());}經過多次執行,結果都是10000。可以說明,CopyOnWriteArraySet是線程安全的Set。
那么CopyOnWriteArraySet是如何保證寫入時的線程安全呢?以下是CopyOnWriteArraySet的add源碼。
????public?boolean?add(E?e)?{return?al.addIfAbsent(e);}public?boolean?addIfAbsent(E?e)?{Object[]?snapshot?=?getArray();return?indexOf(e,?snapshot,?0,?snapshot.length)?>=?0???false?:addIfAbsent(e,?snapshot);}private?static?int?indexOf(Object?o,?Object[]?elements,int?index,?int?fence)?{if?(o?==?null)?{for?(int?i?=?index;?i?<?fence;?i++)if?(elements[i]?==?null)return?i;}?else?{for?(int?i?=?index;?i?<?fence;?i++)if?(o.equals(elements[i]))return?i;}return?-1;}private?boolean?addIfAbsent(E?e,?Object[]?snapshot)?{final?ReentrantLock?lock?=?this.lock;lock.lock();try?{Object[]?current?=?getArray();int?len?=?current.length;if?(snapshot?!=?current)?{//?Optimize?for?lost?race?to?another?addXXX?operationint?common?=?Math.min(snapshot.length,?len);for?(int?i?=?0;?i?<?common;?i++)if?(current[i]?!=?snapshot[i]?&&?eq(e,?current[i]))return?false;if?(indexOf(e,?current,?common,?len)?>=?0)return?false;}Object[]?newElements?=?Arrays.copyOf(current,?len?+?1);newElements[len]?=?e;setArray(newElements);return?true;}?finally?{lock.unlock();}}從源碼可以看出,CopyOnWriteArraySet底層采用了CopyOnWriteArrayList數據結構來實現。在add元素時,采用的是可重入鎖來實現線程安全。
歡迎一鍵三連
推薦一些很不錯的計算機學習教程,包括:數據結構、算法、計算機網絡、操作系統、Java(spring、springmvc、springboot、springcloud等)等等 ,全部收集于網絡,如果有侵權,請聯系刪除!
下面是部分截圖:
獲取方式點擊下方公眾號,回復:好好學Java,即可獲取。總結
以上是生活随笔為你收集整理的Java有线程安全的set吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里排查Java问题工具清单!
- 下一篇: 推荐 7 个牛哄哄 Spring Clo