【Java面試】方法鎖鬧的一個小笑話

當然,笑話的主角就是我本人了,緣由一位羣友關於線程鎖的提問,我直接被帶到溝裏了,典型的審題不認真啊!

-> 羣友
(滑稽) 各位問一個問題
-> 羣友
一個方法synchronized修飾了 裏面就Int++
-> 羣友
幾百個線程調用
-> 羣友
會造成線程不安全嗎
-> 羣友
(滑稽)
-> 羣友
哪裏出了問題呢(滑稽)
-> 羣友
我馬上寫個demo試一下
-> 羣友
會今天給羣裏發紅包

-> 羣友
就開100個線程 調synchronized修飾的int++方法
-> 羣友
隔壁羣一個大佬說會線程安全
-> 羣友
會有問題
-> 羣友
嚇死我了

-> 羣友
還不能說他壞 說他不好還把你踢了 說他懂java
-> 羣友
(滑稽)


當這位羣友這麼說的時候,你猜我寫了一個什麼樣的DEMO去運行。

public class ThreadStudy {

    static int num = 0;

    public static void main(String[] args) {

        for (int i = 0; i < 20000; i++) {
            MyThread t = new MyThread();
            t.start();
        }

    }

}

class MyThread extends Thread {
    @Override
    public void run() {
        test();
    }

    public synchronized void test() {
        ThreadStudy.num++;
        System.out.println(ThreadStudy.num);
    }

}

因爲當羣友說出方法兩個字的時候,我已經默認認爲是實例方法(對象方法);所以理所當然的我也就得出了一個錯誤的答案。

// 第一次
9994
9995
9996
9997
9998
9999

// 第二次
9996
9997
9998
9999
10000

// 第三次
9993
9991
9992
9996
9995
9994

簡單的來說:我上當了!

對象方法和類方法加的鎖完全是兩個概念,當我們在對象方法中加鎖的時候,實際上是對象鎖。

而如果這裏的方法指的是類方法,也就是Static Synchronized,那麼這裏就不是對象鎖了。

Synchronized和Static Synchronized區別

synchronized是對類的當前實例(當前對象)進行加鎖,防止其他線程同時訪問該類的該實例的所有synchronized塊,注意這裏是“類的當前實例”,
類的兩個不同實例就沒有這種約束了。 static synchronized恰好就是要控制類的所有實例的併發訪問,static
synchronized是限制多線程中該類的所有實例同時訪問jvm中該類所對應的代碼塊 實際上,在類中如果某方法或某代碼塊中有
synchronized,那麼在生成一個該類實例後,該實例也就有一個監視塊,防止線程併發訪問該實例的synchronized保護塊,而static
synchronized則是所有該類的所有實例公用得一個監視塊

安慰自己

最後來看看我是怎麼安慰自己的吧。

  1. 一定是題目表述模糊的問題!
  2. “一個方法synchronized修飾了” 並沒有指明是類方法還是實例方法!
  3. 好好學習!

參考資料

Java對象鎖和類鎖全面解析(多線程synchronized關鍵字)
Java類方法和實例方法的區別
深入理解Java中Synchronized(對象鎖)和Static Synchronized(類鎖)的區別


文章中出現的任何錯誤歡迎指正!共同進步!

最後做個小小廣告,有對WEB開發和網絡安全感興趣的,可以加羣一起學習和交流!

交流羣
QQ:425343603

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章