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

java volatile關(guān)鍵字使用方法及注意事項(xiàng)

 更新時(shí)間:2017年07月30日 09:15:12   作者:VikingBird  
這篇文章主要介紹了java volatile關(guān)鍵字使用方法及注意事項(xiàng)的相關(guān)資料,當(dāng)一個(gè)變量被聲明為 volatile 后,java 內(nèi)存模型確保所有使用該變量的線程能看到相同的、一致的值。,需要的朋友可以參考下

java volatile關(guān)鍵字使用方法及注意事項(xiàng)

什么是volatile關(guān)鍵字

volatile 關(guān)鍵字在多線程程序中起著很重要的作用。當(dāng)多個(gè)線程操作同一個(gè)變量時(shí),每個(gè)線程將擁有對那個(gè)變量的本地緩存拷貝,因此,當(dāng)某一個(gè)線程修改了這個(gè)變量的值時(shí),實(shí)際上修改的是它本地緩存中的變量值,而不是主內(nèi)存中的變量值,操作這個(gè)變量的其他線程并不知道這個(gè)變量的值被改變了。為了避免這種情況,我們可以用 valatile 關(guān)鍵字聲明這個(gè)變量,用 valatile 聲明了這個(gè)變量之后,變量將不在本地緩存中保存,而在主內(nèi)存中保存,當(dāng)有線程修改了它的值以后,它的更新值將被更新到主內(nèi)存當(dāng)中,隨后,其他線程也能訪問更新后的值。當(dāng)一個(gè)變量被聲明為 volatile 后,java 內(nèi)存模型確保所有使用該變量的線程能看到相同的、一致的值。

volatile關(guān)鍵字使用

首先,創(chuàng)建 VolatileData 類,代碼如下:

public class VolatileData {

  //聲明為volatile類型
  private volatile int counter = 0;

  /**
  * 返回counter變量的值
  * @return
  */
  public int getCounter() {
    return counter;
  }

  /**
  * 自增counter變量的值
  */
  public void increaseCounter() {
    ++counter;
  }
}

接下來創(chuàng)建 VolatileThread 類,代碼如下:

public class VolatileThread extends Thread {
  private final VolatileData volatileData;

  public VolatileThread(VolatileData volatileData) {
    this.volatileData = volatileData;
  }

  /**
  * 調(diào)用VolatileData類中的兩個(gè)方法,進(jìn)行取值和自增操作
  */
  @Override
  public void run() {
    int oldValue = volatileData.getCounter();
    System.out.println("[Thread " + Thread.currentThread().getId() + "]: Old value = " + oldValue);
    volatileData.increaseCounter();
    int newValue = volatileData.getCounter();
    System.out.println("[Thread " + Thread.currentThread().getId() + "]: New value = " + newValue);
  }
 }

最后,創(chuàng)建 VolatileMain 類,對以上程序進(jìn)行測試,代碼如下:

public class VolatileMain {

  private final static int TOTAL_THREADS = 2;

  public static void main(String[] args) throws InterruptedException {
    VolatileData volatileData = new VolatileData();

    Thread[] threads = new Thread[TOTAL_THREADS];
    for(int i = 0; i < TOTAL_THREADS; ++i)
      threads[i] = new VolatileThread(volatileData);

    //開始讀取變量值的操作
    for(int i = 0; i < TOTAL_THREADS; ++i)
      threads[i].start();

    //等待所有線程操作終止
    for(int i = 0; i < TOTAL_THREADS; ++i)
      threads[i].join();
  }
}

在 VolatileMain 類中,使用了兩個(gè)線程來訪問 volatile 變量,輸出如下:

[Thread 10]: Old value = 0
[Thread 11]: Old value = 0
[Thread 10]: New value = 1
[Thread 11]: New value = 2

從輸出可以看到,首先,兩個(gè)線程都輸出了相同的值,接著,在 increaseCounter 方法被調(diào)用之后,兩個(gè)線程都訪問和輸出了最新的 volatile 變量的值。

happens-before 關(guān)系

在使用 volatile 關(guān)鍵字時(shí),不得不提一下 java 內(nèi)存模型的 happens-before 關(guān)系。happens-before 關(guān)系是 java 內(nèi)存模型的一個(gè)重要方面。它建立在兩個(gè)不同的事件之間,使第一個(gè)事件對對象的所有改變都可以被第二個(gè)事件看到和反映出。比如當(dāng)一個(gè)線程對 volatile 變量進(jìn)行寫操作后,另一個(gè)線程隨后訪問該變量,happens-before 關(guān)系就建立了。因此,所有對 volatile 變量的改變對其他線程來說是可見的。

需要注意的

當(dāng)在程序中使用 volatile 關(guān)鍵字時(shí),我們必須注意以下幾點(diǎn):

  1. volatile 關(guān)鍵字并不能消除原子之間的同步操作的需要,因?yàn)閮?nèi)存一致性錯誤仍然是可能的
  2. 使用原子變量比使用 synchronized 同步代碼更有效率,但是為了避免內(nèi)存一致性錯誤,需要作出額外的努力
  3. volatile 關(guān)鍵字不能替代 synchronized 同步代碼塊和方法

以上就是關(guān)于java volatile關(guān)鍵字的使用方法,如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Java虛擬機(jī)內(nèi)存分配與回收策略問題精細(xì)解讀

    Java虛擬機(jī)內(nèi)存分配與回收策略問題精細(xì)解讀

    Java技術(shù)體系中所提倡的自動內(nèi)存管理最終可以歸結(jié)為自動化地解決了兩個(gè)問題:給對象分配內(nèi)存以及回收分配給對象的內(nèi)存,本文讓我們來詳細(xì)了解
    2021-11-11
  • Java源碼刨析之ArrayDeque

    Java源碼刨析之ArrayDeque

    ArrayDeque是Deque接口的一個(gè)實(shí)現(xiàn),使用了可變數(shù)組,所以沒有容量上的限制。同時(shí),?ArrayDeque是線程不安全的,在沒有外部同步的情況下,不能再多線程環(huán)境下使用<BR>
    2022-07-07
  • Java實(shí)現(xiàn)word,pdf轉(zhuǎn)html并保留格式

    Java實(shí)現(xiàn)word,pdf轉(zhuǎn)html并保留格式

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)將word,pdf轉(zhuǎn)換為html并保留格式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2025-07-07
  • Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例

    Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例

    這篇文章主要介紹了Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot實(shí)現(xiàn)列表數(shù)據(jù)導(dǎo)出為Excel文件

    SpringBoot實(shí)現(xiàn)列表數(shù)據(jù)導(dǎo)出為Excel文件

    這篇文章主要為大家詳細(xì)介紹了在Spring?Boot框架中如何將列表數(shù)據(jù)導(dǎo)出為Excel文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2024-02-02
  • Spring之什么是ObjectFactory?什么是ObjectProvider?

    Spring之什么是ObjectFactory?什么是ObjectProvider?

    這篇文章主要介紹了Spring之什么是ObjectFactory?什么是ObjectProvider?具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 淺談springboot與微服務(wù)架構(gòu)

    淺談springboot與微服務(wù)架構(gòu)

    這篇文章主要介紹了淺談springboot與微服務(wù)架構(gòu),SpringBoot是由 Pivotal團(tuán)隊(duì)提供的框架,其設(shè)計(jì)?的是?來簡化新Spring應(yīng)?,初始搭建以及開發(fā)過程,該框架使?了特定的?式來進(jìn)?配置,需要的朋友可以參考下
    2023-07-07
  • 解決因缺少Log4j依賴導(dǎo)致應(yīng)用啟動失敗的問題

    解決因缺少Log4j依賴導(dǎo)致應(yīng)用啟動失敗的問題

    日志是應(yīng)用軟件中不可缺少的部分,Apache的開源項(xiàng)目log4j是一個(gè)功能強(qiáng)大的日志組件,提供方便的日志記錄。但這篇文章不是介紹Log4j,這篇文章主要介紹了關(guān)于因缺少Log4j依賴導(dǎo)致應(yīng)用啟動失敗問題的相關(guān)資料,需要的朋友可以參考下。
    2017-04-04
  • 關(guān)于MyBatisSystemException異常產(chǎn)生的原因及解決過程

    關(guān)于MyBatisSystemException異常產(chǎn)生的原因及解決過程

    文章講述了在使用MyBatis進(jìn)行數(shù)據(jù)庫操作時(shí)遇到的異常及其解決過程,首先考慮了事務(wù)問題,但未解決,接著懷疑是MyBatis的一級緩存問題,關(guān)閉緩存后問題依舊存在,最終發(fā)現(xiàn)是SQL映射文件中的參數(shù)傳遞錯誤,使用了錯誤的標(biāo)簽導(dǎo)致循環(huán)插入
    2025-01-01
  • java中封裝的實(shí)現(xiàn)方法詳解

    java中封裝的實(shí)現(xiàn)方法詳解

    在本篇文章里我們給大家詳細(xì)分享了關(guān)于java中封裝的實(shí)現(xiàn)方法,有需要的朋友們跟著學(xué)習(xí)下。
    2018-10-10

最新評論

长春市| 寿宁县| 乌审旗| 怀来县| 西宁市| 梅河口市| 新巴尔虎右旗| 钟祥市| 克山县| 团风县| 平遥县| 清远市| 宜良县| 滕州市| 芦山县| 大名县| 绥中县| 宝丰县| 剑川县| 曲麻莱县| 沈丘县| 贵港市| 财经| 沽源县| 安吉县| 突泉县| 龙南县| 诏安县| 日照市| 马鞍山市| 陆良县| 饶平县| 盐池县| 博野县| 阜城县| 杭州市| 洛阳市| 绥滨县| 武安市| 紫阳县| 芷江|