java中的實例鎖(Synchronized)和類鎖(Static Synchronized)

這篇文章我們簡單了解下java中實例鎖和類鎖。

在這里先給個福利,惡補下鎖的作用:對于并發(fā)工作,你需要某種方式來防止兩個任務(wù)訪問相同的資源(其實就是共享資源競爭)。 防止這種沖突的方法就是當(dāng)資源被一個任務(wù)使用時,在其上加鎖。第一個訪問某項資源的任務(wù)必須鎖定這項資源,使其他任務(wù)在其被解鎖之前,就無法訪問它了,而在其被解鎖之時,另一個任務(wù)就可以鎖定并使用它了。

下面進入正題:

實例鎖:對一個類的一個實例對象(對象A)進行加鎖,防止其他線程同時訪問對象A的synchronized塊,但是對不同的此類的實例對象不做控制。實例鎖使用Synchronized關(guān)鍵字修飾。

類鎖:對一個類的所有實例對象進行加鎖,限制多線程中該類的所有實例同時訪問該類的synchronized塊。類鎖使用Static Synchronized關(guān)鍵字修飾。

文字比較生澀,我們看看代碼:

實例鎖

package com.xingshulin;

public class ObjectSyncTest implements Runnable {

    int salary = 0;

    public void run(){
        addSalary();
    }

    public synchronized void addSalary() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        salary += 1;
        System.out.println(salary);
    }

    public static void main(String[] args) {
        ObjectSyncTest st = new ObjectSyncTest();
        for (int i = 0; i < 10; i++) {
            new Thread(st).start();
        }
    }
}

返回結(jié)果:

1
2
3
4
5
6
7
8
9
10

Process finished with exit code 0

代碼很簡單,我們可以看到addSalary方法是使用synchronized修飾的,所以它是實例鎖。在main函數(shù)中我們使用了一個對象st,并生成了10個線程對st對象中的變量salary進行+1操作,可以看到最終結(jié)果確實是同步的。
有些童鞋會問了,那我要是把synchronized關(guān)鍵字去掉呢?其實這就是線程安全的問題了,在這里不多說,但是我們可以看下去掉后的返回值:

5
7
9
9
6
6
9
8
4
7

Process finished with exit code 0

很明顯不對了是吧,再多試幾遍,雖然每次得到的結(jié)果都不同,但是很明顯都是不對的。這就是因為沒有加同步鎖,在程序運行中產(chǎn)生了線程沖突。

類鎖

package com.xingshulin;

public class ClassSyncTest implements Runnable {

    public static int salary = 0;

    public void run(){
        addSalary();
    }

    public static synchronized void addSalary() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        salary += 1;
        System.out.println(salary);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            ClassSyncTest st = new ClassSyncTest();
            new Thread(st).start();
        }
    }
}

返回結(jié)果:

1
2
3
4
5
6
7
8
9
10

Process finished with exit code 0

結(jié)合實例鎖的代碼來看,對比很明顯了。代碼中addSalary方法是使用static synchronized關(guān)鍵字修飾的,所以它是類鎖。而在main函數(shù)中使用了10個不同的對象st,每個對象都對變量salary進行+1操作,可以看到最終結(jié)果也是同步的。
為了證明確實類鎖管用,我們把static關(guān)鍵字刪掉(變成了實例鎖),這樣再跑下程序:

3
3
3
4
8
8
9
5
6
7

Process finished with exit code 0

很明顯,線程又沖突了,所以也正好證明了實例鎖只能管自己的一個實例,對于類中的所有實例是無法做到同步的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容