synchronized和static synchronized的比較


群里討論的一個問題,網上別人已經貼出了很詳細的說明,這里補充記錄下,后面加入個人測試代碼。

起因:1月份的時候看群里討論一道問題,問題內容如下:

   一個日本作者-結成浩的《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){}可以更精確的控制沖突限制訪問區域,有時候表現更高效率。

測試代碼:

  測試環境:jdk1.6.0_30+eclipse3.7

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 
 * @author zm
 *
 */
public class SomeTest {
    
    public static int i;
    
    public synchronized void add(){
        i+=1;
        print();
    }
    
    
    public static synchronized void staticAdd(){
        i+=1;
        print();
    }
    
    public static void print(){
        System.out.println(Thread.currentThread().getName() + "  " + i);
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(20);
        final CountDownLatch ready = new CountDownLatch(20);
        final CountDownLatch start = new CountDownLatch(1);
        final CountDownLatch end = new CountDownLatch(20);
        final SomeTest t = new SomeTest();
        
        for(int i = 0; i < 20; i++){
            pool.execute(new Runnable() {
                
                @Override
                public void run() {
                    ready.countDown();
                    try {
                        start.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    t.add();
                    staticAdd();
                    end.countDown();
                }
            });
        }
        

        
        ready.await();
        System.out.println("ready to execute...");
        start.countDown();
        end.await();
        System.out.println("execute completed. close pool...");
        pool.shutdown();
        
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM