程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java關鍵字volatile和synchronized作用和區別

Java關鍵字volatile和synchronized作用和區別

編輯:關於JAVA

volatile是變量修飾符,而synchronized則是作用於一段代碼或方法;如下三句get代碼:

int i1;
int geti1() {return i1;}

volatile int i2;
int geti2() {return i2;}

int i3;
synchronized int geti3() {return i3;}


    geti1() 得到存儲在當前線程中i1的數值。多個線程有多個i1變量拷貝,而且這些i1之間可以相互不同。換句話說,另一個線程可能已經改變了它線程內的i1值,而這個值可以和當前線程中的i1值不相同。 在Java內存模型中,有main memory(主內存區域),這裡存放了變量目前的“准確值”,每個線程也有自己的memory(例如寄存器)。為了性能,一個線程會在自己的memory中保存要訪問的變量的副本。這樣就會出現同一個變量在某個瞬間,在一個線程的memory中的值可能與另外一個線程memory的值,或者main memory的值不一致的情況。因此實際上存在一種可能:main memory的值i1值是1,線程1裡的i1是2,線程2裡的i1值是3,這在線程1和線程2都改變了他們各自的i1值,而且這個改變還沒來得及傳給main memory 或其他線程時就會發生。

    geti2() 得到的是main memory的i2數值。一個變量聲明為volatile,就意味著這個變量是隨時會被其他線程修改的,因此不能將它cache在線程memory中。換句話說,一個變量經過volatile修飾後在所有線程中必須是同步的,任何線程中改變了它的值,所有其他線程立即獲得了相同的值。所以,volatile修飾的變量存取時比一般變量消耗的資源要多一點,因為線程有它自己的變量拷貝更為高效。

    geti3()方法被synchronized修飾,用synchronized來修飾一個方法或者一個貸款的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。既然volatile關鍵字已經實現了線程間數據同步,又要synchronized干嘛呢?當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步貸款時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊才能執行該代碼塊。然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時候,其他線程對object中所有其他synchronized(this)同步代碼塊的訪問將被阻塞。當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖,結果,其他線程對該對象所有同步代碼部分的訪問都被暫時阻塞。

總結一下區別:

    一,volatile是變量修飾符,而synchronized則作用於一段代碼或者方法。

    二,volatile只是在線程內存和main memory(主內存)間同步某個變量的值;而synchronized通過鎖定和解鎖某個監視器同步所有變量的值。顯然synchronized要比volatile消耗更多資源。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved