1. 程式人生 > >java多執行緒(2) —sychronized

java多執行緒(2) —sychronized

越努力越幸運!

 sychronized篇

一. sychronized的介紹

在Java中內建了語言級的同步原語--synchronized

synchronized是通過互斥達到同步的。

二. sychronized的應用

synchronized關鍵字的作用域有二種:  1)是某個物件例項內,synchronized aMethod(){}可以防止多個執行緒同時訪問這個物件的synchronized方法(如果一個物件有多個synchronized方法,只要一個執行緒訪問了其中的一個synchronized方法,其它執行緒不能同時訪問這個物件中任何一個synchronized方法)。這時,不同的物件例項的synchronized方法是不相干擾的。也就是說,其它執行緒照樣可以同時訪問相同類的另一個物件例項中的synchronized方法;  2)是某個類的範圍,synchronized static aStaticMethod{}防止多個執行緒同時訪問這個類中的synchronized static 方法。它可以對類的所有物件例項起作用。

2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用於方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/*區塊*/},它的作用域是當前物件;

3、synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中並不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;

Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。

     一、當兩個併發執行緒訪問同一個物件object中的這個synchronized(this)同步程式碼塊時,一個時間內只能有一個執行緒得到執行。另一個執行緒必須等待當前執行緒執行完這個程式碼塊以後才能執行該程式碼塊。

     二、然而,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,另一個執行緒仍然可以訪問該object中的非synchronized(this)同步程式碼塊。

     三、尤其關鍵的是,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,其他執行緒對object中所有其它synchronized(this)同步程式碼塊的訪問將被阻塞。

     四、第三個例子同樣適用其它同步程式碼塊。也就是說,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,它就獲得了這個object的物件鎖。結果,其它執行緒對該object物件所有同步程式碼部分的訪問都被暫時阻塞。

     五、以上規則對其它物件鎖同樣適用.

三. sychronized的底層實現

Synchronized的底層實現是依靠moniter鎖的,每一個物件都會帶有一個moniter鎖。與Synchronized實現相關的指令有monitorenter和monitorexit。

每執行一次monitorenter指令的時候,計數器的值就會+1,每執行一次monitorexit指令的時候,計數器的值就會-1,當計數器不為0的時候,還是可以執行monitorenter指令的,這就是可重入性,

每個物件有一個監視器鎖(monitor)。當monitor被佔用時就會處於鎖定狀態,執行緒執行monitorenter指令時嘗試獲取monitor的所有權,過程如下:

如果monitor的計數器為0,則該執行緒進入monitor,然後將計數器數設定為1,該執行緒即為monitor的所有者。

如果執行緒已經佔有該monitor,只是重新進入,則進入monitor的計數器數加1。

如果其他執行緒已經佔用了monitor,則該執行緒進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor的所有權。

 執行monitorexit的執行緒必須是objectref所對應的monitor的所有者。

指令執行時,monitor的計數器數減1,如果減1後進入數為0,那執行緒退出monitor,不再是這個monitor的所有者。

其他被這個monitor阻塞的執行緒可以嘗試去獲取這個monitor 的所有權。

四. sychronized的常見面試題

1.面試官:sychronized lock的區別?

答:1.sychronized是非公平鎖  lock可以是公平鎖和非公平鎖

       2.lock是一個介面,而synchronized是java的一個關鍵字,synchronized是內建的語言實現;

      3.synchronized在發生異常時候會自動釋放佔有的鎖,因此不會出現死鎖;而lock發生異常時候,不會主動釋放佔有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發生。(所以最好將同步程式碼塊用try catch包起來,finally中寫入unlock,避免死鎖的發生。) 

      4.lock等待鎖過程中可以用interrupt來終端等待,而synchronized只能等待鎖的釋放,不能響應中斷;

      5.4. lock可以通過trylock來知道有沒有獲取鎖,而synchronized不能;