激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - ConcurrentMap.putIfAbsent(key,value)用法實例

ConcurrentMap.putIfAbsent(key,value)用法實例

2021-03-31 13:51藍精靈lx Java教程

這篇文章主要介紹了ConcurrentMap.putIfAbsent(key,value)用法實例,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下

本文研究的主要是ConcurrentMap.putIfAbsent(key,value)用法的相關(guān)內(nèi)容,具體如下。

業(yè)務(wù)上經(jīng)常會遇到有這種場景,全局維護一個并發(fā)的ConcurrentMap, Map的每個Key對應(yīng)一個對象,這個對象需要只創(chuàng)建一次。如果Map中該key對應(yīng)的value不存在則創(chuàng)建,否則直接返回。

我們先看一下代碼:

java" id="highlighter_157789">
?
1
2
3
4
5
6
7
8
9
10
11
public static Locale getInstance(String language, String country, 
      String variant) { 
    //... 
    String key = some_string; 
    Locale locale = map.get(key); 
    if (locale == null) { 
      locale = new Locale(language, country, variant); 
      map.put(key, locale); 
    
    return locale; 
  }

這段代碼要做的事情是:

  1. 調(diào)用 map.get(key) 方法,判斷 map 里面是否有該 key 對應(yīng)的 value (Locale 對象)。
  2. 如果返回 null,表示 map 里面沒有要查找的 key-value mapping。new 一個 Locale 對象,并把 new 出來的這個對象與 key 一起放入 map。
  3. 最后返回新創(chuàng)建的 Locale 對象

我們期望每次調(diào)用 getInstance 方法時要保證相同的 key 返回同一個 Local 對象引用。這段代碼能實現(xiàn)這個需求嗎?

答案是:在單線程環(huán)境下可以滿足要求,但是在多線程環(huán)境下會存在線程安全性問題,即不能保證在并發(fā)的情況相同的 key 返回同一個 Local 對象引用。

這是因為在上面的代碼里存在一個習(xí)慣被稱為 put-if-absent 的操作 [1],而這個操作存在一個 race condition:

?
1
2
3
4
if (locale == null) { 
  locale = new Locale(language, country, variant); 
  map.put(key, locale); 
}

因為在某個線程做完 locale == null 的判斷到真正向 map 里面 put 值這段時間,其他線程可能已經(jīng)往 map 做了 put 操作,這樣再做 put 操作時,同一個 key 對應(yīng)的 locale 對象被覆蓋掉,最終 getInstance 方法返回的同一個 key 的 locale 引用就會出現(xiàn)不一致的情形。所以對 Map 的 put-if-absent 操作是不安全的(thread safty)。

為了解決這個問題,java 5.0 引入了 ConcurrentMap 接口,在這個接口里面 put-if-absent 操作以原子性方法 putIfAbsent(K key, V value) 的形式存在。正如 javadoc 寫的那樣:

putIfAbsent方法主要是在向ConcurrentHashMap中添加鍵—值對的時候,它會先判斷該鍵值對是否已經(jīng)存在。

  • 如果不存在(新的entry),那么會向map中添加該鍵值對,并返回null。
  • 如果已經(jīng)存在,那么不會覆蓋已有的值,直接返回已經(jīng)存在的值。

對上面方法進行改造:

?
1
2
3
4
5
6
7
8
9
10
11
public static Locale getInstance(String language, String country, 
      String variant) { 
    //... 
    String key = some_string; 
    Locale locale = map.get(key); 
    if (locale == null) { 
      locale = new Locale(language, country, variant); 
      map.putIfAbsent(key, locale); 
    
    return locale; 
  }

這段代碼使用了 Map 的 concurrent 形式(ConcurrentMap、ConcurrentHashMap),并簡單的使用了語句map.putIfAbsent(key, locale) 。這同樣不能保證相同的 key 返回同一個 Locale 對象引用。

這里的錯誤出在忽視了 putIfAbsent 方法是有返回值的,并且返回值很重要。

所以,使用 putIfAbsent 方法時切記要對返回值進行判斷。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static Locale getInstance(String language, String country, 
      String variant) {
    //... 
    String key = some_string; 
    Locale locale = map.get(key); 
    if (locale == null) { 
      locale = new Locale(language, country, variant); 
      Locale tmp = map.putIfAbsent(key, locale);
      if (tmp != null) {
        locale = tmp;
      }
    
    return locale; 
}

【實例1】

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
    public static void main(String[] args) {
        //測試一下currentHashMap.putIfAbsent()
        Map<long, String> clientMap = new ConcurrentHashMap<>();
        System.out.println("首先打印空的clientMap");
        System.out.println("clientMap: " + clientMap);
        System.out.println();
        //在空的clientMap中添加一個新的記錄
        System.out.println("在空的clientMap中添加一個新的記錄");
        System.out.println("添加之前的clientMap: " + clientMap);
        long netId = 1234567L;
        String str1 = "michael";
        String result = clientMap.putIfAbsent(netId, str1);
        System.out.println("添加之后的clientMap: " + clientMap);
        System.out.println("查看返回值result: " + result);
        System.out.println();
        //重復(fù)添加
        System.out.println("重復(fù)添加上一次的記錄");
        System.out.println("添加之前的clientMap: " + clientMap);
        String result2 = clientMap.putIfAbsent(netId, str1);
        System.out.println("添加之后的clientMap: " + clientMap);
        System.out.println("查看返回值result: " + result2);
        System.out.println();
    }
}

ConcurrentMap.putIfAbsent(key,value)用法實例

總結(jié)

以上就是本文關(guān)于ConcurrentMap.putIfAbsent(key,value)用法實例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/liuxiao723846/article/details/79034556

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美在线观看黄色 | 国产成人高清在线观看 | 视频一区二区视频 | 国产精品视频yy9299一区 | 国产一国产精品一级毛片 | 中文字幕在线观看精品 | 国产精品伊人久久 | 欧美中文字幕一区二区三区亚洲 | 91成人免费| 成人免费激情视频 | 久久我不卡| 青草视频在线观看视频 | chinese中国真实乱对白 | 圆产精品久久久久久久久久久 | 噜噜噜影院 | 国产成人高清成人av片在线看 | 久久成人综合视频 | 国内精品伊人久久 | 亚洲免费视频一区二区 | 99热草| 亚洲精品在线观看网站 | 日产精品久久久久久久 | 日本欧美一区二区三区在线播 | 久久sp | 91精品国产综合久久婷婷香 | 免费视频www在线观看 | 亚洲av一级毛片特黄大片 | 久久精品观看 | 91成人在线网站 | 国产精品久久久久久久久久iiiii | 成人黄视频在线观看 | 特级a欧美做爰片毛片 | 国产一区二区三区视频观看 | 免费a视频| japanesexxxxxxxhd| 亚洲性生活视频 | 少妇的肉体的满足毛片 | 看免费毛片 | 日韩av片在线免费观看 | 欧美77| 欧美亚洲国产成人综合在线 |