国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java中volatile關鍵字的作用與用法詳解

2019-11-26 13:46:43
字體:
來源:轉載
供稿:網友

volatile這個關鍵字可能很多朋友都聽說過,或許也都用過。在Java 5之前,它是一個備受爭議的關鍵字,因為在程序中使用它往往會導致出人意料的結果。在Java 5之后,volatile關鍵字才得以重獲生機。

volatile 關鍵字作用是,使系統中所有線程對該關鍵字修飾的變量共享可見,可以禁止線程的工作內存對volatile修飾的變量進行緩存。

volatile 2個使用場景:

1.可見性:Java提供了volatile關鍵字來保證可見性。

  當一個共享變量被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他線程需要讀取時,它會去內存中讀取新值。

  而普通的共享變量不能保證可見性,因為普通共享變量被修改之后,什么時候被寫入主存是不確定的,當其他線程去讀取時,此時內存中可能還是原來的舊值,因此無法保證可見性。

  另外,通過synchronized和Lock也能夠保證可見性,synchronized和Lock能保證同一時刻只有一個線程獲取鎖然后執行同步代碼,并且在釋放鎖之前會將對變量的修改刷新到主存當中。因此可以保證可見性。

先看一段代碼,假如線程1先執行,線程2后執行:

//線程1boolean stop = false;while(!stop){doSomething();}//線程2stop = true;

  這段代碼是很典型的一段代碼,很多人在中斷線程時可能都會采用這種標記辦法。但是事實上,這段代碼會完全運行正確么?即一定會將線程中斷么?不一定,也許在大多數時候,這個代碼能夠把線程中斷,但是也有可能會導致無法中斷線程(雖然這個可能性很小,但是只要一旦發生這種情況就會造成死循環了)。

  下面解釋一下這段代碼為何有可能導致無法中斷線程。在前面已經解釋過,每個線程在運行過程中都有自己的工作內存,那么線程1在運行的時候,會將stop變量的值拷貝一份放在自己的工作內存當中。

  那么當線程2更改了stop變量的值之后,但是還沒來得及寫入主存當中,線程2轉去做其他事情了,那么線程1由于不知道線程2對stop變量的更改,因此還會一直循環下去。

  但是用volatile修飾之后就變得不一樣了:

  第一:使用volatile關鍵字會強制將修改的值立即寫入主存;

  第二:使用volatile關鍵字的話,當線程2進行修改時,會導致線程1的工作內存中緩存變量stop的緩存行無效(反映到硬件層的話,就是CPU的L1或者L2緩存中對應的緩存行無效);

  第三:由于線程1的工作內存中緩存變量stop的緩存行無效,所以線程1再次讀取變量stop的值時會去主存讀取。

  那么在線程2修改stop值時(當然這里包括2個操作,修改線程2工作內存中的值,然后將修改后的值寫入內存),會使得線程1的工作內存中緩存變量stop的緩存行無效,然后線程1讀取時,發現自己的緩存行無效,它會等待緩存行對應的主存地址被更新之后,然后去對應的主存讀取最新的值。

  那么線程1讀取到的就是最新的正確的值。

2.保證有序性

volatile boolean inited = false;//線程1:context = loadContext(); inited = true; //線程2:while(!inited ){sleep()}doSomethingwithconfig(context);

確保context已經初始化完成。

3.double check

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

以上所述是小編給大家介紹的Java中volatile關鍵字的作用與用法詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿拉善左旗| 莱阳市| 皋兰县| 中山市| 灵宝市| 洛扎县| 乌兰察布市| 徐闻县| 扎囊县| 常州市| 临泽县| 姚安县| 汕头市| 新巴尔虎右旗| 宜宾县| 咸阳市| 长汀县| 墨江| 错那县| 和平区| 桑植县| 宁强县| 棋牌| 溧阳市| 霍山县| 上高县| 鲁山县| 清新县| 昆山市| 竹山县| 淄博市| 广宗县| 海兴县| 康马县| 翁牛特旗| 揭东县| 雅安市| 景宁| 东乌| 新巴尔虎右旗| 石台县|