91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中ConcurrentMap.putIfAbsent(key,value)怎么用

發布時間:2021-08-04 09:48:27 來源:億速云 閱讀:164 作者:小新 欄目:編程語言

小編給大家分享一下java中ConcurrentMap.putIfAbsent(key,value)怎么用,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

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

我們先看一下代碼:

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. 調用 map.get(key) 方法,判斷 map 里面是否有該 key 對應的 value (Locale 對象)。

  2. 如果返回 null,表示 map 里面沒有要查找的 key-value mapping。new 一個 Locale 對象,并把 new 出來的這個對象與 key 一起放入 map。

  3. 最后返回新創建的 Locale 對象

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

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

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

if (locale == null) {  
  locale = new Locale(language, country, variant);  
  map.put(key, locale);  
}

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

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

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

  • 如果不存在(新的entry),那么會向map中添加該鍵值對,并返回null。

  • 如果已經存在,那么不會覆蓋已有的值,直接返回已經存在的值。

對上面方法進行改造:

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 方法時切記要對返回值進行判斷。

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】

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();
		//重復添加 
		System.out.println("重復添加上一次的記錄");
		System.out.println("添加之前的clientMap: " + clientMap);
		String result2 = clientMap.putIfAbsent(netId, str1);
		System.out.println("添加之后的clientMap: " + clientMap);
		System.out.println("查看返回值result: " + result2);
		System.out.println();
	}
}

java中ConcurrentMap.putIfAbsent(key,value)怎么用

看完了這篇文章,相信你對“java中ConcurrentMap.putIfAbsent(key,value)怎么用”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南康市| 新丰县| 彭阳县| 葵青区| 许昌市| 雅江县| 洛南县| 麟游县| 阳朔县| 阳城县| 理塘县| 清徐县| 岑溪市| 佛学| 定远县| 赤峰市| 广元市| 土默特右旗| 南靖县| 阿瓦提县| 东阳市| 余庆县| 富蕴县| 长岛县| 会同县| 江永县| 保亭| 南昌市| 恭城| 石渠县| 双鸭山市| 宁晋县| 彭水| 洛川县| 五大连池市| 五河县| 巴彦县| 沐川县| 东港市| 开阳县| 突泉县|