synchronized類鎖,方法鎖,塊級鎖,一文看懂


先說結論:

1.synchronized加到靜態方法上 調用靜態方法時會鎖住此類,如果此類有2個靜態方法都加上了synchronized則同一時刻只能有一個靜態方法被調用

2.synchronized加到普通方法上 該類的實例(實例指new出來的對象)同一時刻只能調用一個方法,如果多個線程同時調用該實例的多個synchronized方法則只有一個線程會調用到,其他線程會阻塞等待獲取鎖

3.synchronized(obj)放到方法里面作為代碼塊鎖時則要看鎖住的對象是什么:

3.1如果2個方法里面的代碼塊鎖鎖住的對象是同一個則多個線程調用這2個方法時只有一個線程會調用到,其他線程會阻塞等待,類似於2中的方法鎖
3.2如果2個方法里面的代碼塊鎖住的是2個不同的對象則同一時刻允許2個線程同時調用這2個方法,參考下面代碼中Demo類里面的test4和test5

代碼如下:


public class Main {
    public static void main(String[] args) {
        //java.util.concurrent.CopyOnWriteArrayList
        Demo demo = new Demo();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                demo.test3();
                Demo.test5();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                demo.test4();
                Demo.test6();
            }
        });

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                Demo.test5();
            }
        });
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                Demo.test6();
            }
        });

        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}



class Demo{

    private Object obj1 = new Object();
    private Object obj2 = new Object();

    public synchronized void test1(){
        try {
            System.out.println("test1開始執行------"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("test1結束執行------"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public synchronized void test2(){
        try {
            System.out.println("test2開始執行------"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("test2結束執行------"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void test3(){
        synchronized (obj1){
            try {
                System.out.println("test3開始執行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test3結束執行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void test4(){
        synchronized (obj2){
            try {
                System.out.println("test4開始執行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test4結束執行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized static void test5(){
        try {
            System.out.println("test5開始執行------"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("test5結束執行------"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized static void test6(){
        try {
            System.out.println("test6開始執行------"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("test6結束執行------"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


免責聲明!

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



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