Java中的volatile关键字
原博文地址:http://www.cnblogs.com/dolphin0520/p/3920373.html
這里只是對上面的博文的一個簡單總結(jié),總結(jié)如下:
volatile變量保證可見性實(shí)現(xiàn)
volatile變量保證了不同線程對這個變量進(jìn)行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。如何實(shí)現(xiàn):
1. volatile變量規(guī)則:對一個變量的寫操作先行發(fā)生于后面對這個變量的讀操作
2. volatile關(guān)鍵字會強(qiáng)制將修改的值立即寫入主存;
3. 當(dāng)一個線程將共享變量的值修改并將結(jié)果同步到主內(nèi)存當(dāng)中后,其他線程工作內(nèi)存當(dāng)中的緩存值就會失效,即共他線程想再次從自己的工作內(nèi)存當(dāng)中讀取該變量進(jìn)行操作時就會失敗,而是需要從新從主內(nèi)存當(dāng)中讀取。當(dāng)然,如果某個線程已經(jīng)在自己的自己的工作內(nèi)存當(dāng)中讀到了該變量的舊值,那么后面操作該變量的值還是以前的值。所以在多個線程對一個變量進(jìn)行自增時,總是會出現(xiàn)比預(yù)期值要小的結(jié)果。對示例作了圖片化:
示例代碼:
示例圖片:
假如某個時刻,每個線程緩存的變量i的值都是從主內(nèi)存當(dāng)中讀到的10。
線程1在從自己的緩存當(dāng)中讀到10,還未進(jìn)行自增操作時線程1被阻塞了;
當(dāng)然后線程2對變量進(jìn)行讀取并自增,并把11寫入工作內(nèi)存,最后寫入到主存。
然后線程1接著進(jìn)行加1操作,然后將11寫入工作內(nèi)存,最后寫入主存。
那么兩個線程分別進(jìn)行了一次自增操作后,i只增加了1。
所以,在多線程下對某個int類型的變量值時,使用volatile沒有任何用,Java提供了AtomicInteger這種安全的類型,其他基本類型也有對應(yīng)的安全類。
volatile關(guān)鍵字適用場景
1.狀態(tài)標(biāo)記量
有了它修飾才能中斷
volatile boolean flag = false;while(!flag){doSomething(); }public void setFlag() {flag = true; } volatile boolean inited = false; //線程1: context = loadContext(); inited = true; //線程2: while(!inited ){ sleep() } doSomethingwithconfig(context);2.雙重鎖
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;} } 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Java中的volatile关键字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring定时器(@Scheduled
- 下一篇: 《Java设计模式与实践》——工厂模式