成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

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

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

創(chuàng)新互聯(lián)長(zhǎng)期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為義安企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì),義安網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

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

我們先看一下代碼:

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 對(duì)應(yīng)的 value (Locale 對(duì)象)。

  2. 如果返回 null,表示 map 里面沒(méi)有要查找的 key-value mapping。new 一個(gè) Locale 對(duì)象,并把 new 出來(lái)的這個(gè)對(duì)象與 key 一起放入 map。

  3. 最后返回新創(chuàng)建的 Locale 對(duì)象

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

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

這是因?yàn)樵谏厦娴拇a里存在一個(gè)習(xí)慣被稱為 put-if-absent 的操作 [1],而這個(gè)操作存在一個(gè) race condition:

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

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

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

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

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

  • 如果已經(jīng)存在,那么不會(huì)覆蓋已有的值,直接返回已經(jīng)存在的值。

對(duì)上面方法進(jìn)行改造:

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),并簡(jiǎn)單的使用了語(yǔ)句map.putIfAbsent(key, locale) 。這同樣不能保證相同的 key 返回同一個(gè) Locale 對(duì)象引用。

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

所以,使用 putIfAbsent 方法時(shí)切記要對(duì)返回值進(jìn)行判斷。

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;  
}

【實(shí)例1】

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
	public static void main(String[] args) {
		//測(cè)試一下currentHashMap.putIfAbsent() 
		Map<long, String> clientMap = new ConcurrentHashMap<>();
		System.out.println("首先打印空的clientMap");
		System.out.println("clientMap: " + clientMap);
		System.out.println();
		//在空的clientMap中添加一個(gè)新的記錄 
		System.out.println("在空的clientMap中添加一個(gè)新的記錄");
		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();
	}
}

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

看完了這篇文章,相信你對(duì)“java中ConcurrentMap.putIfAbsent(key,value)怎么用”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

當(dāng)前名稱:java中ConcurrentMap.putIfAbsent(key,value)怎么用
網(wǎng)頁(yè)地址:http://jinyejixie.com/article4/jjiioe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、網(wǎng)站制作、網(wǎng)站策劃品牌網(wǎng)站設(shè)計(jì)、Google標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)
汝城县| 老河口市| 罗平县| 莫力| 郴州市| 吉木萨尔县| 荃湾区| 义乌市| 永德县| 永德县| 汕头市| 上饶市| 上犹县| 万全县| 古交市| 青海省| 华蓥市| 巢湖市| 赣州市| 阳城县| 汕头市| 闽侯县| 长顺县| 巴林右旗| 靖州| 扎兰屯市| 灵山县| 玉树县| 洞头县| 田阳县| 隆化县| 鄂伦春自治旗| 澜沧| 平湖市| 和龙市| 泾源县| 碌曲县| 专栏| 固阳县| 普兰店市| 西贡区|