synchronized關鍵字的幾種加鎖方式


1、synchronized的幾種加鎖方式:

(1)synchronized修飾普通方法:在修飾普通方法的時候,這個鎖是當前實例對象,即對象鎖。

  也就是說,這個鎖只對當前的對象實例創建的線程有效,若我們在程序中創建多個對象實例,不同實例分別創建一個線程,這時候這些線程都能同時進到這個方法里,也就是說這個對象鎖,只對當前實例線程有效,多個實例就無效了。

  如下代碼,就是修飾普通方法,但是鎖是無效的,因為這個已經是不同實例了。要想使鎖有效,要保證線程的創建者同屬於一個實例對象。

//鎖失效
public
class Demo1 { static int num = 0; public synchronized void m1(){ for(int i=0;i<10000;i++){ num++; } } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();}); Thread t2 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();}); Thread t3 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();});
t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); System.out.println(num); } }
//鎖有效
public
class Demo1 { static int num = 0; public synchronized void m1(){ for(int i=0;i<10000;i++){ num++; } } public static void main(String[] args) throws InterruptedException { Demo1 demo1 = new Demo1(); Thread t1 = new Thread(()->demo1.m1()); Thread t2 = new Thread(()->demo1.m1()); Thread t3 = new Thread(()->demo1.m1()); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); System.out.println(num); } }

(2)synchronized修飾靜態方法:鎖是當前類Class對象,即類鎖,全局鎖。

  也就是說,這個鎖對於不同實例創建的線程均有效。

public class Demo1 {
    static int num = 0;

    public synchronized static void  m1(){
        for(int i=0;i<10000;i++){
            num++;
        }
    }

    public static class T1 extends Thread{
        @Override
        public void run() {
            Demo1.m1();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        T1 t1 = new T1();
        T1 t2 = new T1();
        T1 t3 = new T1();

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

        t1.join();
        t2.join();
        t3.join();

        System.out.println(num);
    }
}

(3)同步代碼塊,synchronize(class對象){}:這時候這個鎖是全局鎖,對不同實例創建的線程依然有效。

public class Demo1 {
    static int num = 0;

    public  void  m1(){
        // class對象鎖
        synchronized (Demo1.class){
            for(int i=0;i<10000;i++){
                num++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();});
        Thread t2 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();});
        Thread t3 = new Thread(()->{Demo1 demo1 = new Demo1();demo1.m1();});

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

        t1.join();
        t2.join();
        t3.join();

        System.out.println(num);
    }
}

(4)同步代碼塊,synchronize(this){}:傳入的對象為當前實例的時候,這時候就是對象鎖,鎖只對當前實例創建的線程有效。

public class Demo1 {
    static int num = 0;

    public  void  m1(){
        // class對象鎖
        synchronized (this){
            for(int i=0;i<10000;i++){
                num++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Demo1 demo1 = new Demo1();

        Thread t1 = new Thread(()->demo1.m1());
        Thread t2 = new Thread(()->demo1.m1());
        Thread t3 = new Thread(()->demo1.m1());

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

        t1.join();
        t2.join();
        t3.join();

        System.out.println(num);
    }
}

參考博客:https://www.cnblogs.com/chenshy/p/11658691.html 這個寫的比較深入,比較好

參考博客:https://blog.csdn.net/x1107761900/article/details/88713549


免責聲明!

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



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