java中volatile关键字---学习笔记
volatile關鍵字的作用
在java內存模型中,線程之間共享堆內存(對應主內存),但又各自擁有自己的本地內存——棧內存,線程的棧內存中緩存有共享變量的副本,但如果是被volatile修飾的變量,線程每次都直接從堆內存中讀取最新值,并在操作完成時將新值寫入堆內存。
但需要注意的一點是:volatile關鍵字只能保證主存中的變量值是最新的,并不能保證操作的原子性,因此它不能代替synchronized。像簡單的i++也不是原子操作,它包括了read(i),inc(i),write(i)的過程,可能:當一個線程剛從主存中讀取出i的最新值還未進行下一步操作時,另一個線程正往主存中寫入新值,此時就會出現線程不安全的情況。
什么是線程安全?
通俗的解釋就是:有多個線程在同時運行一段代碼,如果每次運行的結果和單線程運行的結果一樣,而且其他的變量值也和預期的一樣,這樣叫做線程安全。例子:一個線程安全的計數器類的同一個實例對象在被多個線程使用的情況下也不會出現計算失誤。
volatile擁有可見性但是不具有原子性的驗證
這里通過創建1000個線程對同一個計數器Counter進行++操作來驗證volatile的線程安全性。為了排除main thread最后讀取count值時,尚有線程沒有結束的情況,這里引入 Java concurrent包里面的一個同步輔助類CountDownLatch,通過countDown()方法和await()方法來保證main thread最后讀取到的count值是主存中最新的。
CountDownLatch latch = new CountDownLatch(1000); //用給定的計數次數1000進行初始化。
latch.countDown(); //此操作是原子操作,即同時只允許有一個線程去減這個計數器里面的值。
latch.await();//在計數器latch里面的值變為0之前一直處于阻塞狀態。
運行結果:
測試結果說明:java中的volatile關鍵字只可保證讀取可見性但并不是線程安全的,在實際使用過程中,我們要具體情況具體分析。
總結
以上是生活随笔為你收集整理的java中volatile关键字---学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文件的上传和下载---学习笔记
- 下一篇: java内存模型---学习笔记