欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java并發(fā)編程如何降低鎖粒度并實(shí)現(xiàn)性能優(yōu)化

 更新時(shí)間:2020年08月29日 08:35:43   作者:程序零世界  
這篇文章主要介紹了Java并發(fā)編程如何降低鎖粒度并實(shí)現(xiàn)性能優(yōu)化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

在高負(fù)載多線(xiàn)程應(yīng)用中性能是非常重要的。為了達(dá)到更好的性能,開(kāi)發(fā)者必須意識(shí)到并發(fā)的重要性。當(dāng)我們需要使用并發(fā)時(shí), 常常有一個(gè)資源必須被兩個(gè)或多個(gè)線(xiàn)程共享。

在這種情況下,就存在一個(gè)競(jìng)爭(zhēng)條件,也就是其中一個(gè)線(xiàn)程可以得到鎖(鎖與特定資源綁定),其他想要得到鎖的線(xiàn)程會(huì)被阻塞。這個(gè)同步機(jī)制的實(shí)現(xiàn)是有代價(jià)的,為了向你提供一個(gè)好用的同步模型,JVM和操作系統(tǒng)都要消耗資源。有三個(gè)最重要的因素使并發(fā)的實(shí)現(xiàn)會(huì)消耗大量資源,它們是:

  • 上下文切換
  • 內(nèi)存同步
  • 阻塞

為了寫(xiě)出針對(duì)同步的優(yōu)化代碼,你必須認(rèn)識(shí)到這三個(gè)因素以及如何減少它們。在寫(xiě)這樣的代碼時(shí)你需要注意很多東西。在本文中,我會(huì)向你介紹一種通過(guò)降低鎖粒度的技術(shù)來(lái)減少這些因素。
讓我們從一個(gè)基本原則開(kāi)始:不要長(zhǎng)時(shí)間持有不必要的鎖。

在獲得鎖之前做完所有需要做的事,只把鎖用在需要同步的資源上,用完之后立即釋放它。我們來(lái)看一個(gè)簡(jiǎn)單的例子:

public class HelloSync {
  private Map dictionary = new HashMap();
  public synchronized void borringDeveloper(String key, String value) {
    long startTime = (new java.util.Date()).getTime();
    value = value + "_"+startTime;
    dictionary.put(key, value);
    System.out.println("I did this in "+
   ((new java.util.Date()).getTime() - startTime)+" miliseconds");
  }
}

在這個(gè)例子中,我們違反了基本原則,因?yàn)槲覀儎?chuàng)建了兩個(gè)Date對(duì)象,調(diào)用了System.out.println(),還做了很多次String連接操作,但唯一需要做同步的操作是“dictionary.put(key, value);”。讓我們來(lái)修改代碼,把同步方法變成只包含這句的同步塊,得到下面更優(yōu)化的代碼:

public class HelloSync {
  private Map dictionary = new HashMap();
  public void borringDeveloper(String key, String value) {
    long startTime = (new java.util.Date()).getTime();
    value = value + "_"+startTime;
    synchronized (dictionary) {
      dictionary.put(key, value);
    }
    System.out.println("I did this in "+
 ((new java.util.Date()).getTime() - startTime)+" miliseconds");
  }
}

上面的代碼可以進(jìn)一步優(yōu)化,但這里只想傳達(dá)出這種想法。如果你對(duì)如何進(jìn)一步優(yōu)化感興趣,請(qǐng)參考java.util.concurrent.ConcurrentHashMap.

那么,我們?cè)趺唇档玩i粒度呢?簡(jiǎn)單來(lái)說(shuō),就是通過(guò)盡可能少的請(qǐng)求鎖。基本的想法是,分別用不同的鎖來(lái)保護(hù)同一個(gè)類(lèi)中多個(gè)獨(dú)立的狀態(tài)變量,而不是對(duì)整個(gè)類(lèi)域只使用一個(gè)鎖。我們來(lái)看下面這個(gè)我在很多應(yīng)用中見(jiàn)到過(guò)的簡(jiǎn)單例子:

public class Grocery {
  private final ArrayList fruits = new ArrayList();
  private final ArrayList vegetables = new ArrayList();
  public synchronized void addFruit(int index, String fruit) {
    fruits.add(index, fruit);
  }
  public synchronized void removeFruit(int index) {
    fruits.remove(index);
  }
  public synchronized void addVegetable(int index, String vegetable) {
    vegetables.add(index, vegetable);
  }
  public synchronized void removeVegetable(int index) {
    vegetables.remove(index);
  }
}

雜貨店主可以對(duì)他的雜貨鋪中的蔬菜和水果進(jìn)行添加/刪除操作。上面對(duì)雜貨鋪的實(shí)現(xiàn),通過(guò)基本的Grocery 鎖來(lái)保護(hù)fruits和vegetables,因?yàn)橥绞窃诜椒ㄓ蛲瓿傻?。事?shí)上,我們可以不使用這個(gè)大范圍的鎖,而是針對(duì)每個(gè)資源(fruits和vegetables)分別使用一個(gè)鎖。來(lái)看一下改進(jìn)后的代碼:

public class Grocery {
  private final ArrayList fruits = new ArrayList();
  private final ArrayList vegetables = new ArrayList();
  public void addFruit(int index, String fruit) {
    synchronized(fruits) fruits.add(index, fruit);
  }
  public void removeFruit(int index) {
    synchronized(fruits) {fruits.remove(index);}
  }
  public void addVegetable(int index, String vegetable) {
    synchronized(vegetables) vegetables.add(index, vegetable);
  }
  public void removeVegetable(int index) {
    synchronized(vegetables) vegetables.remove(index);
  }
}

在使用了兩個(gè)鎖后(把鎖分離),我們會(huì)發(fā)現(xiàn)比起之前用一個(gè)整體鎖,鎖阻塞的情況更少了。當(dāng)我們把這個(gè)技術(shù)用在有中度鎖爭(zhēng)搶的鎖上時(shí),優(yōu)化提升會(huì)更明顯。如果把該方法應(yīng)用到輕微鎖爭(zhēng)搶的鎖上,改進(jìn)雖然比較小,但還是有效果的。但是如果把它用在有重度鎖爭(zhēng)搶的鎖上時(shí),你必須認(rèn)識(shí)到結(jié)果并非總是更好。

請(qǐng)有選擇性的使用這個(gè)技術(shù)。如果你懷疑一個(gè)鎖是重度爭(zhēng)搶鎖請(qǐng)按下面的方法來(lái)確認(rèn)是否使用上面的技術(shù):

  • 確認(rèn)你的產(chǎn)品會(huì)有多少爭(zhēng)搶度,將這個(gè)爭(zhēng)搶度乘以三倍或五倍(甚至10倍,如果你想準(zhǔn)備的萬(wàn)無(wú)一失)
  • 基于這個(gè)爭(zhēng)搶度做適當(dāng)?shù)臏y(cè)試
  • 比較兩種方案的測(cè)試結(jié)果,然后挑選出最合適的.

用于改進(jìn)同步性能的技術(shù)還有很多,但對(duì)所有的技術(shù)來(lái)說(shuō)最基本的原則只有一個(gè):不要長(zhǎng)時(shí)間持有不必要的鎖。

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

相關(guān)文章

  • spring-boot實(shí)現(xiàn)增加自定義filter(新)

    spring-boot實(shí)現(xiàn)增加自定義filter(新)

    本篇文章主要介紹了spring-boot實(shí)現(xiàn)增加自定義filter(新),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Spring?Cloud實(shí)現(xiàn)灰度發(fā)布的示例代碼

    Spring?Cloud實(shí)現(xiàn)灰度發(fā)布的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Spring?Cloud實(shí)現(xiàn)灰度發(fā)布的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-09-09
  • SpringBoot基于SpringSecurity表單登錄和權(quán)限驗(yàn)證的示例

    SpringBoot基于SpringSecurity表單登錄和權(quán)限驗(yàn)證的示例

    這篇文章主要介紹了SpringBoot基于SpringSecurity表單登錄和權(quán)限驗(yàn)證的示例。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Mybatis流式查詢(xún)并實(shí)現(xiàn)將結(jié)果分批寫(xiě)入文件

    Mybatis流式查詢(xún)并實(shí)現(xiàn)將結(jié)果分批寫(xiě)入文件

    這篇文章主要介紹了Mybatis流式查詢(xún)并實(shí)現(xiàn)將結(jié)果分批寫(xiě)入文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 詳解SpringBoot中@ConditionalOnClass注解的使用

    詳解SpringBoot中@ConditionalOnClass注解的使用

    這篇文章主要和大家詳細(xì)介紹一下springboot中@ConditionalOnClass注解的用法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-08-08
  • java判斷是否空最簡(jiǎn)單的方法

    java判斷是否空最簡(jiǎn)單的方法

    在本篇文章里小編給大家整理的一篇關(guān)于java判斷是否空最簡(jiǎn)單的方法,有興趣的讀者們可以參考下。
    2019-12-12
  • springboot使用redis的詳細(xì)步驟

    springboot使用redis的詳細(xì)步驟

    SpringBoot對(duì)常用的數(shù)據(jù)庫(kù)支持外,對(duì)NoSQL?數(shù)據(jù)庫(kù)也進(jìn)行了封裝自動(dòng)化,下面這篇文章主要給大家介紹了關(guān)于springboot使用redis的詳細(xì)步驟,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 一文帶你你搞懂Java的3種IO模型

    一文帶你你搞懂Java的3種IO模型

    在Java中,一共有三種IO模型,分別是阻塞IO(BIO)、非阻塞IO(NIO)和異步IO(AIO),本文將給大家詳解的介紹這三種IO模型,文中有相關(guān)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • apache commons工具集代碼詳解

    apache commons工具集代碼詳解

    這篇文章主要介紹了apache commons工具集代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • java動(dòng)態(tài)線(xiàn)程池的簡(jiǎn)單實(shí)現(xiàn)思路

    java動(dòng)態(tài)線(xiàn)程池的簡(jiǎn)單實(shí)現(xiàn)思路

    本文主要介紹了java?動(dòng)態(tài)線(xiàn)程池的簡(jiǎn)單實(shí)現(xiàn)思路,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論