深刻理解Java中的同步靜態方法和synchronized(class)代碼塊的類鎖

一.回顧學習內容
html

 在前面幾篇博客中我咱們已經理解了synchronized對象鎖、對象鎖的重入、synchronized方法塊、synchronized非本對象的代碼塊,web

 連接:https://www.cnblogs.com/SAM-CJM/category/1314992.html多線程

 咱們來總結一下,上面幾篇講到內容:併發

 1.建立線程類的兩個方式:繼承Thread類和實現Runable接口。異步

 2.瞭解了Thread類的幾個基本構造器。ide

 3.啓動多線程時要使用start方法,不要直接調用run方法。post

 4.幾個多線程中經常使用的方法。學習

 5.解決一個共享資源被多個線程調用時採用了synchronized同步化一個對象的方法。this

 6.一個線程能夠在進入一個同步化的方法時再去進入這個對象的另一個同步化方法,這個就是對象鎖的重入。url

 7.爲了提升程序的執行效率,咱們能夠不去直接同步一個方法,直接同步這個方法中有關共享數據的部分,其餘部分就是異步執行的。

 8.上一篇講到了使用synchronized同步一個不是本對象的代碼塊

二.導入問題

咱們到如今使用的synchronized方法同步的都是非靜態的方法也就是給一個對象上來一把對象鎖,那麼咱們去給一個靜態方法會有什麼效果呢?

三.同步將靜態方法、同步類資源

其實在Java中給一個靜態方法上鎖就是給一個類上鎖,由於類也能夠是一個共享資源。

代碼以下:

public class SynClass {//這個類爲共享資源
    
    //這個靜態方法沒有被同步
    public static void fun() throws InterruptedException {
        System.out.println("**************begin**************");
        Thread.sleep(4000);
        System.out.println("**************end**************");
    }

    public static void main(String[] args) {
       ThreadA t1=new ThreadA();
       ThreadA t2=new ThreadA();
       t1.start();
       t2.start();
    }
}
class ThreadA extends Thread {//建立線程
    @Override
    public void run(){
        try {
            SynClass.fun();//調用靜態方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

結果就是出現了線程不一樣步:

修改代碼以下:

    //這個靜態方法被同步
   synchronized public static void fun() throws InterruptedException {
        System.out.println("**************begin**************");
        Thread.sleep(4000);
        System.out.println("**************end**************");
    }

結果被同步:

說明類也能夠是共享資源,同步靜態方法也是在同步類資源。

四.類鎖和對象鎖的認識

 假如咱們有兩把鎖一把是類鎖,一把是對象鎖,那麼會出現什麼狀況呢?

 代碼以下:

public class SynClassObject {
    //建立一個同步的靜態的方法
    public synchronized static void static_fun(){//類鎖
        System.out.println("**********靜態方法begin*********");
        System.out.println("**********靜態方法end***********");
    }
    //建立同步的非靜態方法
    public synchronized void notStatic_fun(){//對象鎖
        System.out.println("***********非靜態方法begin*************");
        System.out.println("***********非靜態方法end***************");
    }

    public static void main(String[] args) {
        new SynClassObjectThread1().start();
        new SynClassObjectThread2().start();
    }
}

class SynClassObjectThread1 extends Thread{//這個線程類調用的是同步化的靜態方法
    @Override
    public void run(){
        SynClassObject.static_fun();
    }
}

class SynClassObjectThread2 extends Thread{//這個線程類是調用非靜態方法
    private SynClassObject synClassObject =new SynClassObject();
    @Override
    public void run(){
        synClassObject.notStatic_fun();
    }
}

 

 結果入下: 明顯他是不一樣步的,由於對象鎖和類鎖是兩把不一樣的鎖。

 一樣的道理對於同步靜態代碼塊,也是對類資源實現了一個同步。

 

***************************往期博客糾錯******************************

在此要感謝@用戶註冊了一次老哥,幫助指出了深刻理解Java併發synchronized同步化的代碼塊不是this對象時的操做中的錯誤,這一篇文章只是爲了說明synchronized關鍵字同步的是對象而不是方法,我舉的列子的確有失偏頗,本人水平有限,若有錯誤請你們斧正。

 ************************************************************************

相關文章
相關標籤/搜索