synchronized關鍵字有兩種用法。第一種就是在《使用Synchronized關鍵字同步類方法》一文中所介紹的直接用在方法的定義中。 另一種就是synchronized塊。咱們不只能夠經過synchronized塊來同步一個對象變量。也可使用synchronized塊來同步 類中的靜態方法和非靜態方法。
synchronized塊的語法以下:this
1、非靜態類方法的同步 spa
從《使用Synchronized關鍵字同步類方法》一文中咱們知道使用synchronized關鍵字來定義方法就會鎖定類中全部使用 synchronzied關鍵字定義的靜態方法或非靜態方法,但這並很差理解。而若是使用synchronized塊來達到一樣的效果,就不難理解爲何 會產生這種效果了。若是想使用synchronized塊來鎖定類中全部的同步非靜態方法,須要使用this作爲synchronized塊的參數傳入 synchronized塊國,代碼以下:
經過synchronized塊同步非靜態方法code
在上面的代碼中的method1和method2方法中使用了synchronized塊。而第017行的method3方法仍然使用 synchronized關鍵字來定義方法。在使用同一個SyncBlock類實例時,這三個方法只要有一個正在執行,其餘兩個方法就會因未得到同步鎖而 被阻塞。在使用synchronized塊時要想達到和synchronized關鍵字一樣的效果,必須將全部的代碼都寫在synchronized塊 中,不然,將沒法使當前方法中的全部代碼和其餘的方法同步。
除了使用this作爲synchronized塊的參數外,還可使用SyncBlock.this做爲synchronized塊的參數來達到一樣的效果。
在 內類(InnerClass)的方法中使用synchronized塊來時,this只表示內類,和外類(OuterClass)沒有關係。但內類的非靜 態方法能夠和外類的非靜態方法同步。如在內類InnerClass中加一個method4方法,並使method4方法和SyncBlock的三個方法同 步,代碼以下:
使內類的非靜態方法和外類的非靜態方法同步 對象
在上面SyncBlock類的新版本中,InnerClass類的method4方法和SyncBlock類的其餘三個方法同步,所以,method一、method二、method3和method4四個方法在同一時間只能有一個方法執行。
Synchronized塊不論是正常執行完,仍是由於程序出錯而異常退出synchronized塊,當前的synchronized塊所持有的同步鎖都會自動釋放。所以,在使用synchronized塊時沒必要擔憂同步鎖的釋放問題。get
2、靜態類方法的同步
因爲在調用靜態方法時,對象實例不必定被建立。所以,就不能使用this來同步靜態方法,而必須使用Class對象來同步靜態方法。代碼以下:
經過synchronized塊同步靜態方法 同步
在 同步靜態方法時可使用類的靜態字段class來獲得Class對象。在上例中method1和method2方法同時只能有一個方法執行。除了使用 class字段獲得Class對象外,還可使用實例的getClass方法來獲得Class對象。上例中的代碼能夠修改以下:
使用getClass方法獲得Class對象it
在上面代碼中經過一個public的靜態instance獲得一個StaticSyncBlock類的實例,並經過這個實例的getClass方法 獲得了Class對象(一個類的全部實例經過getClass方法獲得的都是同一個Class對象,所以,調用任何一個實例的getClass方法均可 以)。咱們還能夠經過Class對象使不一樣類的靜態方法同步,如Test類的靜態方法method和StaticSyncBlock類的兩個靜態方法同 步,代碼以下:
Test類的method方法和StaticSyncBlock類的method一、method2方法同步io
注意:在使用synchronized塊同步類方法時,非靜態方法可使用this來同步,而靜態方法必須使用Class對象來同步。它們互不影 響。固然,也能夠在非靜態方法中使用Class對象來同步靜態方法。但在靜態方法中不能使用this來同步非靜態方法。這一點在使用 synchronized塊同步類方法時應注意。class