首頁  >  文章  >  Java  >  java 裡面保留字volatile及其與synchronized的區別

java 裡面保留字volatile及其與synchronized的區別

高洛峰
高洛峰原創
2016-12-13 11:20:181362瀏覽

1、鎖提供了兩種主要特性:互斥(mutual exclusion) 和可見性(visibility)。互斥即一次只允許一個執行緒持有某個特定的鎖,因此可使用該特性實現對共享資料的協調存取協議,這樣,一次就只有一個執行緒能夠使用該共享資料。可見性要更加複雜一些,它必須確保釋放鎖之前對共享資料做出的更改對於隨後獲得該鎖的另一個線程是可見的—— 如果沒有同步機制提供的這種可見性保證,則線程看到的共享變數可能是修改前的值或不一致的值,這將引發許多嚴重問題。

2、


在Java中,為了保證多執行緒讀寫資料時保證資料的一致性,可以採用兩種方式:

同步

如用synchronized,或使用鎖定物件.

volatile

使用volatile關鍵字

用一句話概括volatile,它能夠使變數在值發生改變時能盡快地讓其他線程知道.

volatile詳解

首先我們要先意識到有這樣的現象,編譯器為了加快程式運行的速度,對一些變數的寫入操作會先在暫存器或是CPU快取上進行,最後才寫入記憶體.

而在這個過程,變數的新值對其他執行緒是不可見的.而volatile的作用就是使它修飾的變數的讀寫運算都必須在記憶體中進行!

volatile與synchronized

volatile本質是在告訴jvm當前變數在暫存器中的值是不確定的,需要從主存中讀取,synchronized則是鎖定當前變數,只有當前執行緒可以存取該變數,其他執行緒被阻塞住.

volatile僅能使用在變數層級,synchronized則可以使用在變數,方法.
volatile僅能實現變數的修改可見性,但不具備原子特性,而synchronized則可以保證變量的修改可見性和原子性.
volatile不會造成線程的阻塞,而synchronized可能會造成線程的阻塞.
volatile標記的變量不會被編譯器優化,而synchronized標記的變數可以被編譯器優化.

3、因此,在使用volatile關鍵字時要慎重,並不是只要簡單類型變數使用volatile修飾,對這個變數的所有操作都是原來操作,當變數的值由自身的上一個決定時,如n=n+1、n++ 等,volatile關鍵字將失效,只有當變數的值和自身上一個值無關時對該變數的操作才是原子級的,如n = m + 1,這個就是原等級的。所以在使用volatile關鍵時一定要謹慎,如果自己沒有把握,可以使用synchronized來代替volatile。

總結:volatile本質是在告訴JVM目前變數在暫存器中的值是不確定的,需要從主記憶體中讀取。可以實現synchronized的部分效果,但當n=n+1,n++等時,volatile關鍵字將失效,不能起到像synchronized一樣的線程同步的效果。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn