JMM模型到并发编程
電腦:內存 L1 L2 L3 緩存 CPU ctrl+atl+del就可以看到
Java 有線程內存,在執行線程的時候,會從主內存把變量加載到工作內存(緩存),所以,在多線程同時改變一個靜態變量時候,實際是分開相互不影響的
下面是程序例子
以下是運算結果
從此可以看出,第一個線程并沒有退出,initFlag因為在第一個線程沒有變成false,因為是工作內存
?
?
如果想讓第一個內存的變量改變,加一個修飾 volatile
?
工作原理
?
?
在沒有加volatile 時候,線程1沒有store和write回主內存動作有,也沒有重新讀的過程,所以線程1一直在那空轉,也沒有改變。
volatile早期的解決方式,就是單例模式,有且只有一個線程可以訪問到這個主內存的變量
MESI緩存原理 通過嗅探機制 發現主內存在總線里變了,就重新讀取
查看 Java的匯編代碼除了運行程序加以上的參數之外,還要下載工具到jre的bin下(hsdis-amd64)
?
結合配合以volatile的讀/寫和CAS所具有的volatile讀和寫的內存 ,AQS,非阻塞數據結構和原子變量類(java.util.concurrent.atomic包中的類
?
上例子:
不保證原則性
t.join()是等待threads所有的線程都執行完,再去往下執行System.out.println(num);
第一次結果
第二次結果
因為volatile沒辦法保證原子性,在往主內存寫的時候,可能多個線程同時寫會一個值
線程1回寫主內存后,線程2失效了,又重新讀主內存到工作內存,值和線程1的一樣,然后把工作內存寫回主內存,就原來正常先后順序是12,結果同時情況下就變成11
?
?
有序性
運行一下
運行結果是:四種組合結果都有可能 因為CPU會將指令重排序
所以 解決的方法就是在代碼前加volatile?
也就是,加了volatile的代碼,CPU不會重排序把他前面那行代碼放它后面去執行
后續需要繼續學習的知識內容
?
?
?
總結
以上是生活随笔為你收集整理的JMM模型到并发编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几张图可以理解GC JVM调优的内容
- 下一篇: jvm指令码