Java++:synchronized用在普通方法上,代碼塊,靜態方法上的區別

普通方法上:

  synchronized 在普通方法上爲對象鎖,不通對象調用時不會阻塞,相同對象調用時爲同步阻塞。

示例如下:

public class Task {
    public synchronized void funA(){
        System.out.println("======== start running funA ... ========");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("======== end running funA ... ========");
    }

    public synchronized void funB(){
        System.out.println("======== start running funB ... ======== ");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("======== end running funB ... ======== ");
    }
    
    public static void main(String[] args) {
        // 三個線程分別是同的對象調用funA -- 不會阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> new Task().funA()).start();
        }
        // 三個線程分別是同的對象調用funB -- 不會阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> new Task().funB()).start();
        }
        
   
        // 三個線程同的對象調用funA -- 同步阻塞
        Task task = new Task();
        for (int i=0; i<3;i++){
            new Thread(() -> task.funA()).start();
        }
        // 三個線程同的對象調用funB  -- 同步阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> task.funB()).start();
        }

    }
}

代碼塊:

  synchronized(Task.class)爲類鎖,則無論是都相同對象調用都爲同步阻塞.。

  synchronized(this)爲對象鎖,不通對象調用時不會阻塞,相同對象調用時爲同步阻塞。

public class Task {
    public void funC(){
        synchronized(Task.class) {
            System.out.println("======== start running funC ... ========");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("======== end running funC ... ========");
        }
    }

    public void funD(){
        synchronized(this) {
            System.out.println("======== start running funD ... ========");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("======== end running funD ... ========");
        }
    }

    public static void main(String[] args) {
        // 三個線程分別是同的對象調用funC -- 同步阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> new Task().funC()).start();
        }
        // 三個線程分別是同的對象調用funD -- 不會阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> new Task().funD()).start();
        }
    }
}

靜態方法上:

synchronized在靜態方法上爲對象鎖,無論是否同一對象都爲同步阻塞

public class Task {
    public static synchronized void funE(){
        System.out.println("======== start running funE ... ========");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("======== end running funE ... ========");
    }

    public static synchronized void funF(){
        System.out.println("======== start running funF ... ======== ");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("======== end running funF ... ======== ");
    }
    
    public static void main(String[] args) {
        // 三個線程分別是同的對象調用funA -- 同步阻塞
        for (int i=0; i<3;i++){
            new Thread(() -> new Task().funE()).start();
        }
        // 三個線程分別是同的對象調用funD -- 同步阻塞
        Task task = new Task();
        for (int i=0; i<3;i++){
            new Thread(() -> task.funF()).start();
        }
    }
}

總結

對象鎖:同一個對象下是同步阻塞的,不同對象之間非阻塞的。

類鎖:無論是否爲相同對象均爲同步阻塞。

同一個類多個方法被synchronized修飾/代碼塊/靜態方法,則在各個方法之間也是同步阻塞的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章