1. 程式人生 > >Java多執行緒Synchronized的注意細節

Java多執行緒Synchronized的注意細節

      最近做java多執行緒開發處理中發現synchronized的使用還是有一些細節問題要注意的。

     1.synchronized與static synchronized 的區別
      synchronized是對類的當前例項進行加鎖,防止其他執行緒同時訪問該類的該例項的所有synchronized塊,注意這裡是“類的當前例項”,類的兩個不同例項就沒有這種約束了。那麼static synchronized恰好就是要控制類的所有例項的訪問了,static synchronized是限制執行緒同時訪問jvm中該類的所有例項同時訪問對應的程式碼快。實際上,在類中某方法或某程式碼塊中有synchronized,那麼在生成一個該類例項後,改類也就有一個監視快,放置執行緒併發訪問改例項synchronized保護快,而static synchronized則是所有該類的例項公用一個監視快了,也也就是兩個的區別了,也就是synchronized相當於this.synchronized,而
static synchronized相當於Something.synchronized.
      一個日本作者-結成浩的《java多執行緒設計模式》有這樣的一個列子:
      pulbic class Something(){
         public synchronized void isSyncA(){}
         public synchronized void isSyncB(){}
         public static synchronized void cSyncA(){}
         public static synchronized void cSyncB(){}
     }
   那麼,加入有Something類的兩個例項a與b,那麼下列組方法何以被1個以上執行緒同時訪問呢
   a.   x.isSyncA()與x.isSyncB()
   b.   x.isSyncA()與y.isSyncA()
   c.   x.cSyncA()與y.cSyncB()
   d.   x.isSyncA()與Something.cSyncA()
    這裡,很清楚的可以判斷:
   a,都是對同一個例項的synchronized域訪問,因此不能被同時訪問
   b,是針對不同例項的,因此可以同時被訪問
   c,因為是static synchronized,所以不同例項之間仍然會被限制,相當於Something.isSyncA()與   Something.isSyncB()了,因此不能被同時訪問。
   那麼,第d呢?,書上的 答案是可以被同時訪問的,答案理由是synchronzied的是例項方法與synchronzied的類方法由於鎖定(lock)不同的原因。
   個人分析也就是synchronized 與static synchronized 相當於兩幫派,各自管各自,相互之間就無約束了,可以被同時訪問。目前還不是分清楚java內部設計synchronzied是怎麼樣實現的。


   結論:A: synchronized static是某個類的範圍,synchronized static cSync{}防止多個執行緒同時訪問這個    類中的synchronized static 方法。它可以對類的所有物件例項起作用。
  
               B: synchronized 是某例項的範圍,synchronized isSync(){}防止多個執行緒同時訪問這個例項中的synchronized 方法。



     2.synchronized方法與synchronized程式碼快的區別
      synchronized methods(){} 與synchronized(this){}之間沒有什麼區別,只是

synchronized methods(){} 便於閱讀理解,而synchronized(this){}可以更精確的控制衝突限制訪問區域,有時候表現更高效率。