最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java高并發(fā)鎖的3種實(shí)現(xiàn)示例代碼

 更新時(shí)間:2017年08月21日 15:13:40   作者:正在長(zhǎng)大的毛毛蟲  
本篇文章主要介紹了java高并發(fā)鎖的3種實(shí)現(xiàn)示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

初級(jí)技巧 - 樂觀鎖

樂觀鎖適合這樣的場(chǎng)景:讀不會(huì)沖突,寫會(huì)沖突。同時(shí)讀的頻率遠(yuǎn)大于寫。

以下面的代碼為例,悲觀鎖的實(shí)現(xiàn):

public Object get(Object key) { 
  synchronized(map) { 
   if(map.get(key) == null) { 
     // set some values 
   } 
    return map.get(key); 
  } 
} 

樂觀鎖的實(shí)現(xiàn):

public Object get(Object key) { 
  Object val = null; 
  if((val = map.get(key) == null) { 
    // 當(dāng)map取值為null時(shí)再加鎖判斷 
    synchronized(map) { 
      if(val = map.get(key) == null) { 
        // set some value to map... 
      } 
    } 
  } 
  return map.get(key); 
} 

中級(jí)技巧 - String.intern()

樂觀鎖不能很好解決大量寫沖突問題,但是如果很多場(chǎng)景下,鎖實(shí)際上只是針對(duì)某個(gè)用戶或者某個(gè)訂單。比如一個(gè)用戶必須先創(chuàng)建session,才能進(jìn)行后面的操作。但是由于網(wǎng)絡(luò)原因,創(chuàng)建用戶session的請(qǐng)求和后續(xù)請(qǐng)求幾乎同時(shí)達(dá)到,而并行線程可能會(huì)先處理后續(xù)請(qǐng)求。一般情況,需要對(duì)用戶sessionMap加鎖,比如上面的樂觀鎖。在這種場(chǎng)景下,可以講鎖限定到用戶本身上,即從原來的

lock.lock();

  int num=storage.get(key);

  storage.set(key,num+1);

lock.unlock();

更改為:

lock.lock(key);

  int num=storage.get(key);

  storage.set(key,num+1);

lock.unlock(key);

這個(gè)比較類似于數(shù)據(jù)庫(kù)表鎖和行鎖的概念,顯然行鎖的并發(fā)能力比表鎖高很多。

使用String.inter()是這種思路的一種具體實(shí)現(xiàn)。類 String 維護(hù)一個(gè)字符串池。 當(dāng)調(diào)用 intern 方法時(shí),如果池已經(jīng)包含一個(gè)等于此 String 對(duì)象的字符串(該對(duì)象由 equals(Object) 方法確定),則返回池中的字符串??梢?,當(dāng)String相同時(shí),String.intern()總是返回同一個(gè)對(duì)象,因此就實(shí)現(xiàn)了對(duì)同一用戶加鎖。由于鎖的粒度局限于具體用戶,使系統(tǒng)獲得了最大程度的并發(fā)。

public void doSomeThing(String uid) { 
  synchronized(uid.intern()) { 
    // ... 
  } 
}

CopyOnWriteMap?

既然說到了“類似于數(shù)據(jù)庫(kù)中的行鎖的概念”,就不得不提一下MVCC,Java中CopyOnWrite類實(shí)現(xiàn)了MVCC。Copy On Write是這樣一種機(jī)制。當(dāng)我們讀取共享數(shù)據(jù)的時(shí)候,直接讀取,不需要同步。當(dāng)我們修改數(shù)據(jù)的時(shí)候,我們就把當(dāng)前數(shù)據(jù)Copy一份副本,然后在這個(gè)副本 上進(jìn)行修改,完成之后,再用修改后的副本,替換掉原來的數(shù)據(jù)。這種方法就叫做Copy On Write。

但是,,,JDK并沒有提供CopyOnWriteMap,為什么?下面有個(gè)很好的回答,那就是已經(jīng)有了ConcurrentHashMap,為什么還需要CopyOnWriteMap?

Fredrik Bromee 寫道

I guess this depends on your use case, but why would you need a CopyOnWriteMap when you already have a ConcurrentHashMap?

For a plain lookup table with many readers and only one or few updates it is a good fit.

Compared to a copy on write collection:

Read concurrency:

Equal to a copy on write collection. Several readers can retrieve elements from the map concurrently in a lock-free fashion.

Write concurrency:

Better concurrency than the copy on write collections that basically serialize updates (one update at a time). Using a concurrent hash map you have a good chance of doing several updates concurrently. If your hash keys are evenly distributed.

If you do want to have the effect of a copy on write map, you can always initialize a ConcurrentHashMap with a concurrency level of 1.

高級(jí)技巧 - 類ConcurrentHashMap

String.inter()的缺陷是類 String 維護(hù)一個(gè)字符串池是放在JVM perm區(qū)的,如果用戶數(shù)特別多,導(dǎo)致放入字符串池的String不可控,有可能導(dǎo)致OOM錯(cuò)誤或者過多的Full GC。怎么樣能控制鎖的個(gè)數(shù),同時(shí)減小粒度鎖呢?直接使用Java ConcurrentHashMap?或者你想加入自己更精細(xì)的控制?那么可以借鑒ConcurrentHashMap的方式,將需要加鎖的對(duì)象分為多個(gè)bucket,每個(gè)bucket加一個(gè)鎖,偽代碼如下:

Map locks = new Map(); 
List lockKeys = new List(); 
for(int number : 1 - 10000) { 
  Object lockKey = new Object(); 
  lockKeys.add(lockKey); 
  locks.put(lockKey, new Object()); 
}  
public void doSomeThing(String uid) { 
  Object lockKey = lockKeys.get(uid.hash() % lockKeys.size()); 
  Object lock = locks.get(lockKey); 
  synchronized(lock) { 
   // do something 
  } 
} 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    今天帶大家回顧Java基礎(chǔ)的相關(guān)知識(shí),文中對(duì)集合底層原理作了非常詳細(xì)的圖文介紹,對(duì)Java初學(xué)者有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • 超詳細(xì)講解Java秒殺項(xiàng)目登陸模塊的實(shí)現(xiàn)

    超詳細(xì)講解Java秒殺項(xiàng)目登陸模塊的實(shí)現(xiàn)

    這是一個(gè)主要使用java開發(fā)的秒殺系統(tǒng),項(xiàng)目比較大,所以本篇只實(shí)現(xiàn)了登陸模塊,代碼非常詳盡,感興趣的朋友快來看看
    2022-03-03
  • Java中實(shí)現(xiàn)Map按值排序的多種方法

    Java中實(shí)現(xiàn)Map按值排序的多種方法

    Java的Map接口默認(rèn)不保證元素的順序,本文介紹如何使用TreeMap、Collections.sort()結(jié)合Entry、Stream API以及Guava庫(kù)等技術(shù)手段實(shí)現(xiàn)Map按值排序,每種方法都有其特點(diǎn),在選擇具體方法時(shí)應(yīng)考慮項(xiàng)目的具體需求及個(gè)人偏好,需要的朋友可以參考下
    2025-03-03
  • Java實(shí)現(xiàn)多叉樹和二叉樹之間的互轉(zhuǎn)

    Java實(shí)現(xiàn)多叉樹和二叉樹之間的互轉(zhuǎn)

    本文主要介紹了Java實(shí)現(xiàn)多叉樹和二叉樹之間的互轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 淺談Java中浮點(diǎn)型數(shù)據(jù)保留兩位小數(shù)的四種方法

    淺談Java中浮點(diǎn)型數(shù)據(jù)保留兩位小數(shù)的四種方法

    今天在進(jìn)行開發(fā)的過程中遇到了一個(gè)小問題,是關(guān)于如何將double類型的數(shù)據(jù)保留兩位小數(shù)。具有一定的參考價(jià)值,本文就詳細(xì)的介紹一下
    2021-09-09
  • Mybatis 動(dòng)態(tài)SQL的幾種實(shí)現(xiàn)方法

    Mybatis 動(dòng)態(tài)SQL的幾種實(shí)現(xiàn)方法

    這篇文章主要介紹了Mybatis 動(dòng)態(tài)SQL的幾種實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 詳解在Spring Boot中使用Mysql和JPA

    詳解在Spring Boot中使用Mysql和JPA

    本文向你展示如何在Spring Boot的Web應(yīng)用中使用Mysq數(shù)據(jù)庫(kù),也充分展示Spring Boot的優(yōu)勢(shì)
    2017-04-04
  • Java通過SSLEngine與NIO實(shí)現(xiàn)HTTPS訪問的操作方法

    Java通過SSLEngine與NIO實(shí)現(xiàn)HTTPS訪問的操作方法

    這篇文章主要介紹了Java通過SSLEngine與NIO實(shí)現(xiàn)HTTPS訪問,需要在Connect操作、Connected操作、Read和Write操作中加入SSL相關(guān)的處理即可,需要的朋友可以參考下
    2021-08-08
  • 使用Mybatis遇到的坑之Integer類型參數(shù)的解讀

    使用Mybatis遇到的坑之Integer類型參數(shù)的解讀

    這篇文章主要介紹了使用Mybatis遇到的坑之Integer類型參數(shù)的解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 詳解Java語言中一個(gè)字符占幾個(gè)字節(jié)?

    詳解Java語言中一個(gè)字符占幾個(gè)字節(jié)?

    這篇文章主要介紹了Java語言中一個(gè)字符占幾個(gè)字節(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論

靖西县| 永吉县| 张家港市| 永吉县| 木里| 汶川县| 德钦县| 乾安县| 晴隆县| 开鲁县| 安溪县| 安丘市| 双峰县| 名山县| 罗江县| 太白县| 永昌县| 高清| 屯留县| 新建县| 平昌县| 开远市| 榆中县| 陇南市| 宾川县| 大渡口区| 金昌市| 沅陵县| 舟山市| 云霄县| 霍城县| 海晏县| 大理市| 青浦区| 皋兰县| 荔浦县| 应城市| 大城县| 上杭县| 水富县| 舞阳县|