亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java多線程并發(fā)編程 并發(fā)三大要素

 更新時(shí)間:2017年05月22日 22:57:42   投稿:mdxy-dxy  
這篇文章主要介紹了Java多線程并發(fā)編程 并發(fā)三大要素,需要的朋友可以參考下

一、原子性

原子,一個(gè)不可再被分割的顆粒。原子性,指的是一個(gè)或多個(gè)不能再被分割的操作。

int i = 1; // 原子操作
i++; // 非原子操作,從主內(nèi)存讀取 i 到線程工作內(nèi)存,進(jìn)行 +1,再把 i 寫到朱內(nèi)存。

雖然讀取和寫入都是原子操作,但合起來(lái)就不屬于原子操作,我們又叫這種為“復(fù)合操作”。

我們可以用synchronized 或 Lock 來(lái)把這個(gè)復(fù)合操作“變成”原子操作。

例子:

 private synchronized void increase(){
    i++;
  }

 private int i = 0;
  Lock mLock = new ReentrantLock();

  private void increase() {
    mLock.lock();
    try {
      i++;
    } finally{
      mLock.unlock();
    }
  }

這樣我們就可以把這個(gè)一個(gè)方法看做一個(gè)整體,一個(gè)不可分割的整體。

除此之前,我們還可以用java.util.concurrent.atomic里的原子變量類,可以確保所有對(duì)計(jì)數(shù)器狀態(tài)訪問(wèn)的操作都是原子的。

例子:

AtomicInteger mAtomicInteger = new AtomicInteger(0);
 
  private void increase(){
    mAtomicInteger.incrementAndGet();
  }

二、可見性

當(dāng)多線程訪問(wèn)某一個(gè)(同一個(gè))變量時(shí),其中一條線程對(duì)此變量作出修改,其他線程可以立刻讀取到最新修改后的變量。

int i = 0;
// 線程 1 執(zhí)行
i++;

// 線程 2 執(zhí)行
System.out.print("i=" + i);

即使是在執(zhí)行完線程里的 i++ 后再執(zhí)行線程 2,線程 2 的輸入結(jié)果也會(huì)有 2 個(gè)種情況,一個(gè)是 0 和 1。

因?yàn)?i++ 在線程 1(CPU1)中做完了運(yùn)算,并沒(méi)有立刻更新到主內(nèi)存當(dāng)中,而線程 2(CPU2)就去主內(nèi)存當(dāng)中讀取并打印,此時(shí)打印的就是 0。

synchronized和Lock能夠保證可見性。

另外volatile關(guān)鍵字也可以解決這個(gè)問(wèn)題(下一篇會(huì)講到)。

三、有序性

我們都知道處理器為了擁有更好的運(yùn)算效率,會(huì)自動(dòng)優(yōu)化、排序執(zhí)行我們寫的代碼,但會(huì)確保執(zhí)行結(jié)果不變。

例子:

int a = 0; // 語(yǔ)句 1
int b = 0; // 語(yǔ)句 2
i++; // 語(yǔ)句 3
b++; // 語(yǔ)句 4

這一段代碼的執(zhí)行順序很有可能不是按上面的 1、2、3、4 來(lái)依次執(zhí)行,因?yàn)?1 和 2 沒(méi)有數(shù)據(jù)依賴,3 和 4 沒(méi)有數(shù)據(jù)依賴, 2、1、4、3 這樣來(lái)執(zhí)行可以嗎?完全沒(méi)問(wèn)題,處理器會(huì)自動(dòng)幫我們排序。

在單線程看來(lái)并沒(méi)有什么問(wèn)題,但在多線程則很容易出現(xiàn)問(wèn)題。

再來(lái)個(gè)例子:

// 線程 1
init();
inited = true;

// 線程 2
while(inited){
	work();
}

init(); 與 inited = true; 并沒(méi)有數(shù)據(jù)的依賴,在單線程看來(lái),如果把兩句的代碼調(diào)換好像也不會(huì)出現(xiàn)問(wèn)題。

但此時(shí)處于一個(gè)多線程的環(huán)境,而處理器真的把這兩句代碼重新排序,那問(wèn)題就出現(xiàn)了,若線程 1 先執(zhí)行 inited = true; 此時(shí),init() 并沒(méi)有執(zhí)行,線程 2 就已經(jīng)開始調(diào)用 work() 方法,此時(shí)很可能造成一些奔潰或其他 BUG 的出現(xiàn)。

synchronized和Lock能確保原子性,能讓多線程執(zhí)行代碼的時(shí)候依次按順序執(zhí)行,自然就具有有序性。

而volatile關(guān)鍵字也可以解決這個(gè)問(wèn)題,volatile 關(guān)鍵字可以保證有序性,讓處理器不會(huì)把這行代碼進(jìn)行優(yōu)化排序。

相關(guān)文章

  • metershpere實(shí)現(xiàn)調(diào)用自定義jar包中的方法

    metershpere實(shí)現(xiàn)調(diào)用自定義jar包中的方法

    在MeterSphere接口測(cè)試中,面對(duì)多層循環(huán)邏輯和邏輯判斷等復(fù)雜情況,直接編寫測(cè)試用例往往顯得混亂不便,本文介紹了一個(gè)簡(jiǎn)化這一過(guò)程的方法:首先使用IDEA創(chuàng)建Maven工程,編寫所需邏輯并生成jar包;然后在MeterSphere中上傳此jar包
    2024-10-10
  • Java基礎(chǔ)之Bean的創(chuàng)建、定位和使用

    Java基礎(chǔ)之Bean的創(chuàng)建、定位和使用

    這篇文章主要介紹了Java基礎(chǔ)之Bean的創(chuàng)建、定位和使用,文中有非常詳細(xì)的圖文示例及代碼,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java面試題沖刺第二十一天--JVM

    Java面試題沖刺第二十一天--JVM

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 詳解IDEA用maven創(chuàng)建springMVC項(xiàng)目和配置

    詳解IDEA用maven創(chuàng)建springMVC項(xiàng)目和配置

    本篇文章主要介紹了詳解IDEA用maven創(chuàng)建springMVC項(xiàng)目和配置 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • mybatis關(guān)系映射之一對(duì)多和多對(duì)一

    mybatis關(guān)系映射之一對(duì)多和多對(duì)一

    今天小編就為大家分享一篇關(guān)于mybatis關(guān)系映射之一對(duì)多和多對(duì)一,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • Java8中的Stream流式操作教程之王者歸來(lái)

    Java8中的Stream流式操作教程之王者歸來(lái)

    這篇文章主要給大家介紹了關(guān)于Java8中Stream流式操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java8具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • springboot配置ldaps連接方式

    springboot配置ldaps連接方式

    這篇文章主要介紹了springboot配置ldaps連接方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 最新評(píng)論