synchronized、volatile區別、synchronized鎖粒度、模擬死鎖場景、原子性與可見性

synchronized、volatile區別、synchronized鎖粒度

synchronized

synchronized是Java中的關鍵字,是一種同步鎖。有以下幾種用法:

用法

1、修飾方法:在範圍操作符之後,返回類型聲明之前使用。每次只能有一個線程進入該方法,
		此時線程獲得的是成員鎖。
2、修飾代碼塊:每次只能有一個線程進入該代碼塊,
		此時線程獲得的是成員鎖。
3、修飾對象:如果當前線程進入,那麼其他線程在該類所有對象上的任何操作都不能進行,
		此時當前線程獲得的是對象鎖。
4、修飾類:如果當前線程進入,那麼其他線程在該類中所有操作不能進行,包括靜態變量和靜態方法,
		此時當前線程獲得的是對象鎖。

volatile

volatile 關鍵字的作用是禁止指令的重排序,強制從公共堆棧中取得變量的值,而不是從線程私有的數據棧中取變量的值。

  • volatile與synchronized的區別如下:

1)volatile本質是告訴JVM當前變量在寄存器中的值是不確定的,需要從主存中讀取。synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其它線程被阻塞。
2)volatile僅能使用在變量級別,synchronized則可以使用在變量、方法。
3)volatile僅能實現變量修改的可見性,而synchronized則可以保證變量修改的可見性和原子性。《Java編程思想》上說,定義long或double時,如果使用volatile關鍵字(簡單的賦值與返回操作),就會獲得原子性。(常規狀態下,這兩個變量由於其長度,其操作不是原子的)
4)volatile不會造成線程阻塞,synchronized會造成線程阻塞。
5)使用volatile而不是synchronized的唯一安全情況是類中只有一個可變的域。

lock

  • synchronized是隱式鎖,在需要同步的對象中加入此控制,而lock是顯示鎖,需要顯示指定起始位置和終止位置。
  • 使用lock時在finally中必須釋放鎖,不然容易造成線程死鎖;而使用synchronized時,獲取鎖的線程會在執行完同步代碼後釋放鎖(或者JVM會在線程執行發生異常時釋放鎖)。
    使用lock時線程不會一直等待;而使用synchronized時,假設A線程獲得鎖後阻塞,其他線程會一直等待。
  • lock可重入、可中斷、可公平也可不公平;而synchronized可重入但不可中斷、非公平。

模擬死鎖場景

https://blog.csdn.net/a158123/article/details/78616562

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