一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java volatile關鍵字使用方法及注意事項

java volatile關鍵字使用方法及注意事項

2020-12-08 13:44VikingBird Java教程

這篇文章主要介紹了java volatile關鍵字使用方法及注意事項的相關資料,當一個變量被聲明為 volatile 后,java 內存模型確保所有使用該變量的線程能看到相同的、一致的值。,需要的朋友可以參考下

java volatile關鍵字使用方法及注意事項

什么是volatile關鍵字

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

volatile關鍵字使用

首先,創建 VolatileData 類,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class VolatileData {
 
  //聲明為volatile類型
  private volatile int counter = 0;
 
  /**
  * 返回counter變量的值
  * @return
  */
  public int getCounter() {
    return counter;
  }
 
  /**
  * 自增counter變量的值
  */
  public void increaseCounter() {
    ++counter;
  }
}

接下來創建 VolatileThread 類,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class VolatileThread extends Thread {
  private final VolatileData volatileData;
 
  public VolatileThread(VolatileData volatileData) {
    this.volatileData = volatileData;
  }
 
  /**
  * 調用VolatileData類中的兩個方法,進行取值和自增操作
  */
  @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);
  }
 }

最后,創建 VolatileMain 類,對以上程序進行測試,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 類中,使用了兩個線程來訪問 volatile 變量,輸出如下:

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

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

happens-before 關系

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

需要注意的

當在程序中使用 volatile 關鍵字時,我們必須注意以下幾點:

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

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

原文鏈接:https://my.oschina.net/dabird/blog/904430

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 性导航h | 精东影业传媒全部作品 | 视频在线91 | 久久综合网久久综合 | 欧美日韩国产在线一区 | 色综合视频一区二区三区 | 免费看日韩 | 四虎永久在线精品国产 | 69老司机亚洲精品一区 | 亚洲欧洲淘宝天堂日本 | 日本特级大片 | 性色AV一区二区三区V视界影院 | 91国内精品久久久久影院优播 | 秋霞在线观看成人高清视频51 | 厨房play黄瓜进入 | 添逼逼视频 | 69日本xxxxxxxxx98 69人成网站色www | 国产永久免费爽视频在线 | 国产欧美国产精品第一区 | 日日网| 欧美有码 | 亚洲精品视频久久 | caoporn草棚在线视频 | 四虎影视在线影院在线观看观看 | 无人区国产大片 | 欧美四虎影院 | 窝窝影院午夜色在线视频 | 免费在线观看a | 四虎影院在线免费 | zoomkool最新版 | 亚洲六月丁香六月婷婷色伊人 | 99久久伊人精品波多野结衣 | a男人的天堂久久a毛片 | 亚洲国产在线视频中文字 | 色婷婷六月天 | 精品夜夜澡人妻无码AV蜜桃 | 国产精品29页 | chinese老太granny chinese国产人妖hd | 小鸟酱在线看 | 办公室恋情在线 | 色噜噜狠狠狠综合曰曰曰88av |