synchronized(this)與synchronized(class)

原文:http://www.cnblogs.com/highriver/archive/2011/12/18/2291965.html


synchronized(class)很特別,它會讓另一個線程在任何需要獲取class做爲monitor的地方等待.class與this做爲不同的監視器可以同時使用,不存在一個線程獲取了class,另一個線程就不能獲取該class的一切實例.

 

根據下面的代碼自行修改,分別驗證下面的幾種情況:

synchronized(class)
synchronized(this)
->線程各自獲取monitor,不會有等待.
synchronized(this)
synchronized(this)
->如果不同線程監視同一個實例對象,就會等待,如果不同的實例,不會等待.
synchronized(class)
synchronized(class)
->如果不同線程監視同一個實例或者不同的實例對象,都會等待.

複製代碼
package thread.sync;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RunnableTest implements Runnable {

    private static boolean flag = true;

//    private static synchronized void testSyncMethod() { // 注意static修改的同步方法,監視器=class
//        for (int i = 0; i < 100; i++) {
//            System.out.println("testSyncMethod:" + i);
//        }
//    }

    private void testSyncMethod() { 
        synchronized (this) {
            for (int i = 0; i < 100; i++) {
                System.out.println("testSyncMethod:" + i);
            }
        }
    }

    private void testSyncBlock() {

        synchronized (this) { // 注意this做爲監視器.它與class分別是二個不同監視器.不會存在class被獲取,this就要等的現象.這也是我以前關於監視器的一個誤區.
            for (int i = 0; i < 100; i++) {
                System.out.println("testSyncBlock:" + i);
            }
        }

        // synchronized (RunnableTest.class) { // 顯示使用獲取class做爲監視器.它與static synchronized method隱式獲取class監視器一樣.
        // for (int i = 0; i < 100; i++) {
        // System.out.println("testSyncBlock:" + i);
        // }
        // }
    }

    public void run() {

        // flag是static的變量.所以,不同的線程會執行不同的方法,只有這樣才能看到不同的鎖定效果.
        if (flag) {
            flag = false;
            testSyncMethod();
        } else {
            flag = true;
            testSyncBlock();
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(2);
        RunnableTest rt = new RunnableTest();
        RunnableTest rt1 = new RunnableTest();
        exec.execute(rt);
        exec.execute(rt1);
        exec.shutdown();
    }
}

發佈了0 篇原創文章 · 獲贊 9 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章