成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何保證HashSet線程安全?

開發 前端
在本文中,我們看到了不同的創建線程安全的Set的方式,也比較了他們之間的差異性。 所以大家以后使用的時候,可以考慮使用ConcurrentHashMap創建的Set。

大家好,我是指北君。

線程安全的問題,真的算是老生常談了。這幾天看到一個 HashSet 線程安全的騷操作,在這里分享給大家。 在本文中,我們將分享如何構造線程安全的HashSet的幾種方法。

使用ConcurrentHashMap工廠方法構造線程安全的HashSet

首先, 我們來看看_ConcurrentHashMap_暴露出來的靜態方法 -- newKeySet()。此方法返回一個Set的實例,等同于實現了 java.util.Set 接口,而且能夠使用Set的一些常用操作,比如 add(), contains() 等。

舉個例子:

Set<Integer> threadSafeUniqueNumbers = ConcurrentHashMap.newKeySet();
threadSafeUniqueNumbers.add(23);
threadSafeUniqueNumbers.add(45);

這里返回的Set,其實有點類似于 HashSet,因為兩者都是基于Hash算法實現的,另外線程同步邏輯帶來的額外開銷也很小,因為它最終還是 ConcurrentHashMap 的一部分。

不過,這個只能在 Java 8 以上版本才可以使用,我想大部分公司應該至少 Java 8 了吧。直接拿來用就行。

現在,我們已經了解了可以用 ConcurrentHashMap#newKeySet()構建類似于線程安全的HashSet,在 ConcurrentHashMap 其實被定義為 KeySetView。ConcurrentHashMap 其實還有兩個實例方法可以用于構建 KeySetView, 一個是 keySet() 另外一個就是keySet(defaultValue), 我這里就簡寫一下了, 大家可以在IDE中直接打出來看看。

這兩個方法都可以創建KeySetView的實例,KeySetView 與 Map 是一個連接的關系。 我們每次向Map中添加新的鍵值對的時候,Set中的數據也在相應的添加,我們通過幾個例子來看看這兩種方法有哪些區別。

KeySet() 方法

keySet() 方法 和 keySet(defaultValue) ,最大的區別就是不能直接往Set中添加數據。直接添加的話,會拋出 UnsupportedOperationException 異常,源碼中的定義如下。

public KeySetView<K,V> keySet(){
KeySetView<K,V> ks;
if ((ks = keySet) != null) return ks;
return keySet = new KeySetView<K,V>(this, null);
}
// add
public boolean add(K e){
V v;
if ((v = value) == null)
throw new UnsupportedOperationException();
return map.putVal(e, v, true) == null;
}

所以我們只能通過如下的方式使用。

ConcurrentHashMap<Integer,String> numbersMap = new ConcurrentHashMap<>();
Set<Integer> numbersSet = numbersMap.keySet();

numbersMap.put(1, "One");
numbersMap.put(2, "Two");
numbersMap.put(3, "Three");

System.out.println("Map before remove: "+ numbersMap);
System.out.println("Set before remove: "+ numbersSet);

numbersSet.remove(2);

System.out.println("Set after remove: "+ numbersSet);
System.out.println("Map after remove: "+ numbersMap);

輸出結果如下。

Map before remove: {1=One, 2=Two, 3=Three}
Set before remove: [1, 2, 3]

Set after remove: [1, 3]
Map after remove: {1=One, 3=Three}

KeySet(defaultValue) 方法

keySet(defaultValue) ,由于有設置默認的value,可以在添加的時候不會報錯,JDK 源碼縱定義如下:

public KeySetView<K,V> keySet(V mappedValue){
if (mappedValue == null)
throw new NullPointerException();
return new KeySetView<K,V>(this, mappedValue);
}

所以我們可以通過如下的方式使用。

ConcurrentHashMap<Integer,String> numbersMap = new ConcurrentHashMap<>();
Set<Integer> numbersSet = numbersMap.keySet("SET-ENTRY");

numbersMap.put(1, "One");
numbersMap.put(2, "Two");
numbersMap.put(3, "Three");

System.out.println("Map before add: "+ numbersMap);
System.out.println("Set before add: "+ numbersSet);

numbersSet.addAll(asList(4,5));

System.out.println("Map after add: "+ numbersMap);
System.out.println("Set after add: "+ numbersSet);

輸出結果如下:

Map before add: {1=One, 2=Two, 3=Three}
Set before add: [1, 2, 3]
Map after add: {1=One, 2=Two, 3=Three, 4=SET-ENTRY, 5=SET-ENTRY}
Set after add: [1, 2, 3, 4, 5]

使用Collections的來創建線程安全的 Set

java.util.Collections 中有一個線程同步的方法可以用于創建,示例代碼如下。

Set<Integer> syncNumbers = Collections.synchronizedSet(new HashSet<>());
syncNumbers.add(1);

這個方法的性能并沒有ConcurrentHashMap的那個效率高,由于使用了同步鎖,增加了一些額外的開銷。

使用CopyOnWriteArraySet構建線程安全的 Set

用CopyOnWriteArraySet 創建線程安全的 set 也是非常簡單的。示例代碼如下

Set<Integer> copyOnArraySet = new CopyOnWriteArraySet<>();
copyOnArraySet.add(1);

這個方法從性能的角度上來看,也不是很理想,CopyOnWriteArraySet 背后的實現是CopyOnWriteArrayList, 最終使用了數組來存儲數據,也就意味著 contains() 或者 remove() 操作,具有 O(n) 的復雜度,而使用HashMap 復雜度為 O(1) 。

建議使用此實現時,設置大小通常保持較小,只讀操作占大多數。

總結

在本文中,我們看到了不同的創建線程安全的Set的方式,也比較了他們之間的差異性。 所以大家以后使用的時候,可以考慮使用ConcurrentHashMap創建的Set。

責任編輯:武曉燕 來源: Java技術指北
相關推薦

2024-06-17 00:02:00

線程安全HashMapJDK 1.7

2024-05-20 13:13:01

線程安全Java

2021-12-21 07:07:43

HashSet元素數量

2021-05-26 08:49:15

API接口安全

2011-09-23 10:13:43

2024-11-26 07:29:57

高并發線程安全

2022-06-07 23:28:05

線程安全后端

2022-09-26 13:46:18

Java線程安全

2012-03-07 10:00:35

2013-07-16 14:10:03

2020-06-12 10:03:01

線程安全多線程

2010-09-06 09:27:54

社交網絡

2010-10-08 10:17:59

Web服務安全

2021-06-30 13:31:18

線程安全ThreadLocal

2023-09-07 10:41:54

物聯網食品安全

2022-04-22 16:11:12

區塊鏈數據安全去中心化

2017-11-03 13:48:59

ERP信息化數據

2024-05-06 13:36:41

2013-08-20 09:26:03

大數據時代hadoop

2019-03-13 08:28:28

物聯網設計物聯網安全物聯網
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区播放 | 一区二区视频 | 中文字幕一区在线观看视频 | 日韩在线免费视频 | 国产2区| 日韩天堂av | 日韩免费激情视频 | 国产高清在线精品一区二区三区 | 亚洲激情一区二区三区 | 精品中文字幕在线观看 | 午夜av毛片 | 日韩在线免费播放 | 日韩视频一区 | 亚洲啊v在线 | 99综合网 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 国产精品1区2区3区 欧美 中文字幕 | 国产精品久久久久久一级毛片 | 成人在线看片 | 久久久久国产精品一区二区 | 欧美日韩综合精品 | 91精品国产91久久久久久吃药 | 欧美一级二级视频 | 亚洲欧美一区二区三区在线 | 青青草社区| 日韩欧美在线免费观看 | 91麻豆产精品久久久久久夏晴子 | 做a视频| 国产高清视频一区二区 | av中文在线观看 | 在线a视频 | 久久人 | 99精品国产一区二区三区 | 黄色大片视频 | 精品三级在线观看 | 天天综合网天天综合 | 一区二区三区在线播放视频 | 一区二区三区国产好的精 | 亚洲国产高清高潮精品美女 | 在线看日韩 | 国产精品国产三级国产aⅴ中文 |