Java併發之synchronized關鍵字

synchronized關鍵字

1 簡單介紹

  • synchronized 是java語言關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,可以保證在同一時刻最多隻有一個線程執行該段代碼。
  • synchronized 關鍵字,它包括兩種用法:synchronized 方法和 synchronized 塊。

2 能夠修飾哪些內容

  • 1、 修飾一個代碼塊,被修飾的代碼塊稱爲同步語句塊,其做用的範圍是大括號{}括起來的代碼,做用的對象是調用這個代碼塊的對象;java

  • 2、修飾一個方法,被修飾的方法稱爲同步方法,其做用的範圍是整個方法,做用的對象是調用這個方法的對象;併發

  • 3、修飾一個靜態的方法,其做用的範圍是整個靜態方法,做用的對象是這個類的全部對象;函數

  • 4、修飾一個類,其做用的範圍是synchronized後面括號括起來的部分,做用的對象是這個類的全部對象。this

3.synchonized(this)和synchonized(object)區別

  • 其實並無很大的區別,synchonized(object)自己就包含synchonized(this)這種狀況,使用的場景都是對一個代碼塊進行加鎖,效率比直接在方法名上加synchonized高一些(下面分析),惟一的區別就是對象的不一樣。線程

  • 對synchronized(this)的一些理解對象

    • 1、當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程獲得執行。另外一個線程必須等待當前線程執行完這個代碼塊之後才能執行該代碼塊。同步

    • 2、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另外一個線程仍然能夠訪問該object中的非synchronized(this)同步代碼塊。class

    • 3、尤爲關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其餘線程對object中全部其它synchronized(this)同步代碼塊的訪問將被阻塞。效率

    • 4、當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就得到了這個object的對象鎖。結果,其它線程對該object對象全部同步代碼部分的訪問都被暫時阻塞。變量

4.sychonized method 和 synchonized代碼塊的效率問題

  • 使用前者的對象會獲取該對象中全部synchonized的鎖,也就是其餘線程不能訪問全部加了synchonized前綴的方法(不單單只是當前運行的方法),影響了其餘線程同步方法的訪問,下降了效率。然後者只對當前代碼塊加鎖,其餘的同步方法不受影響。

5.結論

  • 1.synchronized 方法控制對類成員變量的訪問:每一個類實例對應一把鎖,每一個 synchronized 方法都必須得到調用該方法的類實例的鎖方能執行,不然所屬線程阻塞,方法一旦執行,就獨佔該鎖,直到從該方法返回時纔將鎖釋放,此後被阻塞的線程方能得到該鎖,從新進入可執行狀態。這種機制確保了同一時刻對於每個類實例,其全部聲明爲 synchronized 的成員函數中至多隻有一個處於可執行狀態(由於至多隻有一個可以得到該類實例對應的鎖),從而有效避免了類成員變量的訪問衝突(只要全部可能訪問類成員變量的方法均被聲明爲 synchronized)。

  • 2.synchronized 塊是這樣一個代碼塊,其中的代碼必須得到對象 syncObject (如前所述,能夠是類實例或類)的鎖方能執行。因爲能夠針對任意代碼塊,且可任意指定上鎖的對象,故靈活性較高。

  • 3.在static方法前加synchronized:靜態方法屬於類方法,它屬於這個類,獲取到的鎖,是屬於類的鎖。

  • 4.在普通方法前加synchronized:非static方法獲取到的鎖,是屬於當前對象的鎖。

  • 5.類鎖和對象鎖不一樣,synchronized修飾不加static的方法,鎖是加在單個對象上,不一樣的對象沒有競爭關係;修飾加了static的方法,鎖是加載類上,這個類全部的對象競爭一把鎖。

相關文章
相關標籤/搜索