synchronized三種使用方式,及鎖的類型驗證


Synchronized常用三種使用方式

1、修飾普通方法:鎖對象即為當前對象

2、修飾靜態方法:鎖對象為當前Class對象

3、修飾代碼塊:鎖對象為synchronized緊接着的小括號內的對象

一、驗證修飾普通方法時鎖對象

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {
        Thread t1 = new MyThread1();
        Thread t2 = new MyThread2(t1);

        t1.start();// 默認priority=5
        t2.start();

        t2.setPriority(9);
System.out.println(
"線程1:" + t1.getState()); System.out.println("線程2:" + t2.getState()); } } class MyThread1 extends Thread { @Override public void run() { dosome(); } public synchronized void dosome() { System.out.println("mythread1"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sleep end"); } } class MyThread2 extends Thread { private Object lock; public MyThread2(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("mythread2"); } } }

現象:先逐行輸出mythread1,線程1:RUNNABLE,線程2:BLOCKED,之后暫停五分鍾,逐行輸出sleep end,mythread2

分析:線程2與線程1擁有相同的鎖,線程1優先級高於線程2,線程1優先執行,獲取到鎖,執行sleep,未釋放鎖,線程2未獲取到鎖,處於阻塞狀態,線程1sleep結束,輸出sleep end,並釋放鎖,線程2獲取到鎖,執行輸出mythread2

結論:當synchronized修飾普通方法時,鎖對象即為當前對象

二、驗證修飾靜態方法時鎖對象

對上述代碼稍作修改,在dosome方法上添加static關鍵字,main方法中,線程2對象初始化時,傳入MyThread1.class

現象:與上述現象一致

分析:同上

結論:當synchronized修飾靜態方法時,鎖對象為當前Class對象

三、驗證修飾代碼塊時鎖對象

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {
        Object o = new Object();

        Thread t1 = new MyThread1(o);
        Thread t2 = new MyThread2(o);

        t1.start();
        t2.start();

        t2.setPriority(9);
        System.out.println("線程1:" + t1.getState());
        System.out.println("線程2:" + t2.getState());

    }

}

class MyThread1 extends Thread {
    private Object lock;

    public MyThread1(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {

        synchronized (lock) {
            System.out.println("mythread1");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sleep end");
        }
    }

}

class MyThread2 extends Thread {
    private Object lock;

    public MyThread2(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("mythread2");
        }
    }

}

現象:同上

分析:同上

結論:當使用synchronized修改代碼塊時,其后小括號中的對象即為對象鎖。

 


免責聲明!

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



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