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

解析java中volatile關(guān)鍵字

 更新時(shí)間:2016年01月14日 14:21:38   作者:石頭_ly  
這篇文章主要為大家解析了java中volatile關(guān)鍵字,經(jīng)常有人把volatile關(guān)鍵字和synchronized或者lock混淆,本文就為大家好好區(qū)分,感興趣的小伙伴們可以參考一下

在java多線程編程中經(jīng)常volatile,有時(shí)候這個(gè)關(guān)鍵字和synchronized 或者lock經(jīng)常有人混淆,具體解析如下:
在多線程的環(huán)境中會(huì)存在成員變量可見性問題: java的每個(gè)線程都存在一個(gè)線程棧的內(nèi)存空間,該內(nèi)存空間保存了該線程運(yùn)行時(shí)的變量信息,當(dāng)線程訪問某一個(gè)變量值的時(shí)候首先會(huì)根據(jù)這個(gè)變量的地址找到對(duì)象的堆內(nèi)存或者是棧堆存(原生數(shù)據(jù)類型)中的具體的內(nèi)容,然后把這個(gè)內(nèi)同賦值一個(gè)副本保存在本線程的線程棧中,緊接著對(duì)這個(gè)變量的一切操作在線程完成退出之前都和堆棧內(nèi)存中的變量?jī)?nèi)容是沒有關(guān)系的,操作的是自己線程棧中的副本。當(dāng)操作完后會(huì)把操作完的結(jié)果寫回到主內(nèi)存中。假如有兩個(gè)線程A和B,同事操作某一個(gè)變量x;A對(duì)x進(jìn)行了加1操作,那么B獲取的副本可能是x加1后的結(jié)果,也可能是x;為了保證獲取內(nèi)存中最新的數(shù)據(jù)變量 需要加上 volatile 關(guān)鍵字,這樣在每次對(duì)x進(jìn)行操作的時(shí)候都會(huì)去檢查下線程棧中的變量的值是不是和住內(nèi)存中變量的值一樣,如果不一樣會(huì)重新load。
eg:

public class ThreadSee { 
//t1線程會(huì)根據(jù)flag的值做對(duì)應(yīng)的操作,主線程會(huì)更改t1的值 
 public static void main(String[] args) throws InterruptedException { 
    ThReadTest th= new ThReadTest(); 
    Thread t1 = new Thread(th); 
    t1.start(); 
    Thread.sleep(1000); 
    th.changeFlag(); 
    Thread.sleep(2000); 
    System.out.println(th.getFlag()); 
  } 
 
} 
 
 
class ThReadTest implements Runnable{ 
 
  //線程訪問變量時(shí)會(huì)把其load到對(duì)應(yīng)的線程棧中,每次操作時(shí)都要獲取內(nèi)存中最新的數(shù)據(jù) 
  private volatile boolean stopflag; 
  @Override 
  public void run() { 
    int i=0; 
    while(!stopflag){ 
      i++; 
      System.out.println("=="+Thread.currentThread().getName()); 
    } 
    System.out.println("Thread finish:"+i); 
  } 
  public void changeFlag(){ 
    this.stopflag=true; 
    System.out.println(Thread.currentThread().getName()+"***********"); 
  } 
 
  public boolean getFlag(){ 
    return stopflag; 
  } 
} 

上述代碼如果去掉volatile,會(huì)一直死循環(huán)執(zhí)行下去。
但是volatile不能保證線程安全的同步
eg:

public class ThreadSave implements Runnable{ 
  static ThreadSave sync = new ThreadSave(); 
  static volatile int j=0; 
  //Lock lock =new ReentrantLock(); 
  public void inscane(){ 
    // lock.lock(); 
    for(int i=0;i<10000000;i++){ 
      j++; 
    } 
   //  lock.unlock(); 
  } 
  @Override 
  public void run() { 
    inscane(); 
  } 
  public static void main(String[] args) throws InterruptedException { 
    Thread t1 = new Thread(sync); 
    Thread t2 = new Thread(sync); 
    t1.start(); 
    t2.start(); 
    t1.join(); 
    t2.join(); 
    System.out.println(j); 
  } 
} 

根據(jù)上述代碼執(zhí)行的結(jié)果不是預(yù)期20000000,
因?yàn)閷?duì)于volatile修飾的變量,jvm虛擬機(jī)只是保證從主內(nèi)存加載到線程工作內(nèi)存的值是最新的。
例如假如線程1,線程2 在進(jìn)行線程棧與主內(nèi)存read,load 操作中,發(fā)現(xiàn)主內(nèi)存中count的值都是5,那么都會(huì)加載這個(gè)最新的值
在線程1堆count進(jìn)行修改之后,會(huì)write到主內(nèi)存中,主內(nèi)存中的count變量就會(huì)變?yōu)?;
線程2由于已經(jīng)進(jìn)行read,load操作,在進(jìn)行運(yùn)算之后,也會(huì)更新主內(nèi)存count的變量值為6;
導(dǎo)致兩個(gè)線程及時(shí)用volatile關(guān)鍵字修改之后,還是會(huì)存在并發(fā)的情況。
綜上所述:
volatile只會(huì)保證線程去做一個(gè)檢查當(dāng)前線程棧的變量值和主內(nèi)存中數(shù)據(jù)值是否一樣的這么一個(gè)動(dòng)作,只此而已。而lock或者是synchronized 會(huì)保證某一時(shí)刻只有單個(gè)線程進(jìn)入該方法,從而確保其線程安全性。
所以在如果多個(gè)線程去修改一個(gè)volatile變量那么沒有實(shí)際的邏輯意義。如果一個(gè)線程去修改其他的線程依賴修改的變量值,此時(shí)是有作用的。

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

相關(guān)文章

  • Java中斷線程的方法

    Java中斷線程的方法

    這篇文章主要介紹了Java中斷線程的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-05-05
  • Spring Boot Thymeleaf實(shí)現(xiàn)國(guó)際化的方法詳解

    Spring Boot Thymeleaf實(shí)現(xiàn)國(guó)際化的方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot Thymeleaf實(shí)現(xiàn)國(guó)際化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component的深度解析

    Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component的深度解析

    在現(xiàn)代微服務(wù)架構(gòu)中,動(dòng)態(tài)配置管理是一個(gè)關(guān)鍵需求,Spring Cloud 提供了 @RefreshScope 注解,允許應(yīng)用在運(yùn)行時(shí)動(dòng)態(tài)更新配置,而無需重啟服務(wù),本文深入探析Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component,感興趣的朋友一起看看吧
    2025-04-04
  • MybatisPlus之likeRight的用法

    MybatisPlus之likeRight的用法

    這篇文章主要介紹了MybatisPlus之likeRight的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java注解方式之防止重復(fù)請(qǐng)求

    Java注解方式之防止重復(fù)請(qǐng)求

    這篇文章主要介紹了關(guān)于Java注解方式防止重復(fù)請(qǐng)求,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java?多線程并發(fā)ReentrantLock

    Java?多線程并發(fā)ReentrantLock

    這篇文章主要介紹了Java?多線程并發(fā)ReentrantLock,Java?提供了?ReentrantLock?可重入鎖來提供更豐富的能力和靈活性,感興趣的小伙伴可以參考一下
    2022-06-06
  • java事件處理模型知識(shí)點(diǎn)總結(jié)

    java事件處理模型知識(shí)點(diǎn)總結(jié)

    在本篇文章里小辮給大家分享的是一篇關(guān)于java事件處理模型知識(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • Spring boot中使用Spring-data-jpa方便快捷的訪問數(shù)據(jù)庫(推薦)

    Spring boot中使用Spring-data-jpa方便快捷的訪問數(shù)據(jù)庫(推薦)

    Spring Data JPA 是 Spring 基于 ORM 框架、JPA 規(guī)范的基礎(chǔ)上封裝的一套JPA應(yīng)用框架,可使開發(fā)者用極簡(jiǎn)的代碼即可實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問和操作。這篇文章主要介紹了Spring-boot中使用Spring-data-jpa方便快捷的訪問數(shù)據(jù)庫,需要的朋友可以參考下
    2018-05-05
  • 基于Java編寫串口通信工具

    基于Java編寫串口通信工具

    這篇文章主要為大家詳細(xì)介紹了基于Java編寫的一個(gè)帶有圖形界面的簡(jiǎn)單串口通信工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 淺談Ribbon、Feign和OpenFeign的區(qū)別

    淺談Ribbon、Feign和OpenFeign的區(qū)別

    這篇文章主要介紹了淺談Ribbon、Feign和OpenFeign的區(qū)別。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評(píng)論

潢川县| 赞皇县| 丽江市| 甘肃省| 屯门区| 永州市| 江山市| 仪陇县| 永嘉县| 资中县| 康平县| 揭东县| 凤冈县| 长子县| 凤凰县| 新兴县| 田东县| 庄浪县| 土默特右旗| 青龙| 灌阳县| 广南县| 广元市| 峨眉山市| 固安县| 深泽县| 永登县| 南漳县| 永春县| 双牌县| 阿巴嘎旗| 太保市| 周至县| 江川县| 济源市| 绍兴县| 林周县| 珠海市| 吉林省| 即墨市| 车险|