synchronized和volatile的一些問題

關於java多線程的一些常見問題。

①java的內存可見性模型


故每個線程都有自己的工作內存。從主內存中讀取X的值,改變X的值之後將最新的值寫入到主內存之中,各個線程之間通過主內存進行交流。

②java中的內存可見性

內存可見性指的是比如線程一每次從主內存中讀取最新的X的值。改變X後立馬將X值刷新到主內存之中。

③原子性操作

比如X++;這一操作就不是原子性操作。它可以分解爲三步操作。首先線程從主內存中讀取X的值,然後在自己的工作內存中對X做出修改,最後將X的值刷新到主內存中。


synchronized和volatile的比較:

synchronized能夠同時保證內存可見性和原子性操作。但是volatile只能保證內存可見性,也就是每次都是從內存中讀取最新的數據,修改之後立馬刷新到內存區。但是卻不會保證原子性操作。所以volatile不能保證X++操作的多線程安全,但是synchronized卻可以。

爲什麼volatilevo不能保證X++操作的多線程安全:


比如有兩個線程A和B,同時X的初始值是5,接着執行了下面的操作。

①A 首先從主內存中讀取到了X的值,這時它的CPU將執行權交給了B。故A只是讀取了X的值,但是還沒有做出修改。

②B從主內存中讀取X的值,這時是5

③B執行X++操作,將B的值改爲6

④B將X的值刷新到主內存中

⑤A獲得CPU執行權,執行X++操作。(注意:執行X++操作之前在A的工作內存中X的值是5)將X變爲6

⑥將X的最新值6刷新到主內存之中

所以經過以上步驟,理論上X應該是7,應爲有兩次++操作,但是由於volatile不能保證操作的原子性,所以導致結果不一定符合預期,也就是說volatile不能保證多線程安全






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章