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

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

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

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

public class ThreadSee { 
//t1線程會根據(jù)flag的值做對應的操作,主線程會更改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{ 
 
  //線程訪問變量時會把其load到對應的線程棧中,每次操作時都要獲取內(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á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é)果不是預期20000000,
因為對于volatile修飾的變量,jvm虛擬機只是保證從主內(nèi)存加載到線程工作內(nèi)存的值是最新的。
例如假如線程1,線程2 在進行線程棧與主內(nèi)存read,load 操作中,發(fā)現(xiàn)主內(nèi)存中count的值都是5,那么都會加載這個最新的值
在線程1堆count進行修改之后,會write到主內(nèi)存中,主內(nèi)存中的count變量就會變?yōu)?;
線程2由于已經(jīng)進行read,load操作,在進行運算之后,也會更新主內(nèi)存count的變量值為6;
導致兩個線程及時用volatile關(guān)鍵字修改之后,還是會存在并發(fā)的情況。
綜上所述:
volatile只會保證線程去做一個檢查當前線程棧的變量值和主內(nèi)存中數(shù)據(jù)值是否一樣的這么一個動作,只此而已。而lock或者是synchronized 會保證某一時刻只有單個線程進入該方法,從而確保其線程安全性。
所以在如果多個線程去修改一個volatile變量那么沒有實際的邏輯意義。如果一個線程去修改其他的線程依賴修改的變量值,此時是有作用的。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助。

相關(guān)文章

  • Java實現(xiàn)5種負載均衡算法(小結(jié))

    Java實現(xiàn)5種負載均衡算法(小結(jié))

    負載均衡是將客戶端請求訪問,通過提前約定好的規(guī)則轉(zhuǎn)發(fā)給各個server,本文主要介紹了Java實現(xiàn)5種負載均衡算法,具有一定的參考價值,感興趣的可以了解一下
    2022-06-06
  • JDK8新出Optional類的方法探索與思考分析

    JDK8新出Optional類的方法探索與思考分析

    這篇文章主要為大家介紹了JDK8新出Optional類的發(fā)方法示例探索與思考分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Java反射 PropertyDescriptor類案例詳解

    Java反射 PropertyDescriptor類案例詳解

    這篇文章主要介紹了Java反射 PropertyDescriptor類案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • IntelliJ IDEA快速查看某個類/接口的子類或父類

    IntelliJ IDEA快速查看某個類/接口的子類或父類

    本文主要介紹了IntelliJ IDEA快速查看某個類/接口的子類或父類,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Mybatis-plus4條件構(gòu)造器使用方式

    Mybatis-plus4條件構(gòu)造器使用方式

    這篇文章主要介紹了Mybatis-plus4條件構(gòu)造器使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 常用Java排序算法詳解

    常用Java排序算法詳解

    本文主要介紹了java的七種常見排序算法的實現(xiàn),對選擇排序、插入排序、冒泡排序、歸并排序、快速排序、希爾排序、最小堆排序進行原理分析與實例介紹,具有很好的參考價值。下面就跟著小編一起來看下吧
    2016-12-12
  • Java實現(xiàn)DES加解密算法解析

    Java實現(xiàn)DES加解密算法解析

    這篇文章主要介紹了Java實現(xiàn)DES加解密算法解析,結(jié)合完整實例形式分析了DES加密的相關(guān)原理,需要的朋友可以參考下。
    2016-10-10
  • Open?Feign之非SpringCloud方式使用示例

    Open?Feign之非SpringCloud方式使用示例

    這篇文章主要為大家介紹了Open?Feign之非SpringCloud方式使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • 一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J

    一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J

    本文主要介紹了一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • SpringBoot RestTemplate GET POST請求的實例講解

    SpringBoot RestTemplate GET POST請求的實例講解

    這篇文章主要介紹了SpringBoot RestTemplate GET POST請求的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論