日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

volatile关键字解析

發布時間:2024/7/19 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 volatile关键字解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

volatile:

1.保證可見性

2.禁止重排序

我們先來看看一個問題,關于i=i+1的問題。

首先,他不是一個原子性的操作,我們通常將不可拆分的操作稱為原子操作

而i=i+1需要先在主存中取得i的值,之后復制到高速緩存之中,CPU再從高速緩存中讀取并計算之后存入高速緩存,最后把值再存入內存中。

那么怎么來解決這個問題呢?

有兩種方法

第一種是Lock加鎖,但是一定會損失并發性,加鎖之后其他cpu無法訪問

第二種是保證可見性,即當前cpu對這個數據進行更改時,其他數據也可以看到修改。

這個是通過共享變量來判斷的,將這個數據設置為共享數據,如果這個數據發生改變,其他持有該數據的cpu都會得到通知,將自己持有的作廢之后重新在內存中獲取。

上面我們講了一下關于可見性的問題

?

那么下面我們來聊一聊關于重排序的問題

什么是重排序呢,在遵守happens--before的原則下,操作系統可以對一些指令進行重排序

比如:

a=1

a++

b=1

我們將第二條和第三條語句交換位置,并不會改變結果

但是有時,看上去互不影響的語句交換順序是會影響最終結果的

例如:

//線程1?

int a=1

int flag = true;

?

//線程二

if(flag){

xxxxxxxxxxxx

}

?

如上,我們本來打算是線程1完成所有的初始化操作之后再執行線程二

但是如果重排序,線程一的兩條語句重排之后,那么a還沒有完成初始化,線程二就會執行。

?

如果我們用volatile使得禁止指令重排序

我們會在這條語句上添加內存屏障

即保證這條語句前面的語句都在這條語句之前執行

保證這條語句后面的語句都在這條語句之后執行

但是他前面幾條語句,以及后面幾條語句的執行順序并不保證

?

volatile只能保證內存一致性,而不能保證原子性

保證原子性需要synchronized或者lock

public class Main {public volatile int inc = 0;public void increase() {inc++;}public static void main(String[] args) {final Main test = new Main();for(int i=0;i<10;i++){new Thread(){public void run() {for(int j=0;j<1000;j++)test.increase();};}.start();}while(Thread.activeCount()>1) //保證前面的線程都執行完Thread.yield();System.out.println(test.inc);} }

?

最終inc的結果一定小于10000

因為inc++并不是原子性操作

我們前面說過,需要先在主存中取得i的值,之后復制到高速緩存之中,CPU再從高速緩存中讀取并計算之后存入高速緩存,最后把值再存入內存中。

所有比如現在inc=1

當線程1讀取了inc的值,輪到線程二執行,線程二對inc讀取并加1,因為線程1只是讀取,所以線程二對數據的更改線程一并不知道,線程二將2寫入內存,線程一又將讀取的數據自增,最后還是2

本來應該是3 ,結果就出現了偏差

所以要保證正確性,就必須保證操作是原子性的

否則使用synchronized或者lock

?

volatile還有一個經典的使用案例

單例模式中的雙重鎖

public class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) {// 1 if (instance == null) {// 2 instance = new Singleton();// 3 } } } return instance; } }

?

總結

以上是生活随笔為你收集整理的volatile关键字解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。