成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Synchronized關鍵字的底層原理?

開發 前端
在 Java 中,關鍵字 synchronized 可以保證在同一個時刻,只有一個線程可以執行某個方法或者某個代碼塊(主要是對方法或者代碼塊中存在共享數據的操作),同時我們還應該注意到 synchronized 的另外一個重要的作用,synchronized 可保證一個線程的變化(主要是共享數據的變化)被其他線程所看到。

1. synchronized的基本使用

在現實場景中,搶票代碼,如果不加鎖,就會出現超賣或者一張票賣給多個人

Synchronized對象鎖采用互斥的方式讓同一時刻至多只有一個線程能持有對象鎖,其它線程再想獲取這個對象鎖時就會阻塞住,代碼如下

public class synchronizedTest {
    // 創建一個靜態對象作為鎖
    static Object lock = new Object();
    // 初始票數
    int ticketNum = 20;

    // 獲取票的方法,使用 synchronized 修飾確保線程安全
    public synchronized void getTicket() {
        // 使用當前對象作為鎖
        synchronized (this) {
            // 如果票數已經為零,則返回
            if (ticketNum <= 0) {
                return;
            }
            System.out.println(Thread.currentThread().getName() + "搶到一張票,剩余:" + ticketNum);
            // 非原子性操作,扣除一張票
            ticketNum--;
        }
    }

    public static void main(String[] args) {
        // 創建 synchronizedTest 實例
        synchronizedTest synchronizedTest = new synchronizedTest();
        // 創建并啟動 20 個線程
        for (int i = 0; i < 20; i++) {
            // 調用獲取票的方法
            new Thread(() -> synchronizedTest.getTicket()).start();
        }
    }
}

通過以上代碼,加synchronized鎖,就可以防止超賣

特別說明:synchronized 關鍵字的底層實現涉及到 Java 虛擬機中的監視器(Monitor)機制。每個 Java 對象都與一個 Monitor 相關聯,Monitor 負責對象的鎖定和解鎖,以及線程的阻塞和喚醒。

2. Monitor

Monitor 被翻譯為監視器,是由jvm提供,c++語言實現

使用一下簡單代碼中查看monitor,通過javap命令查看clsss的字節碼

public class MonitorTest {
    static final Object lock = new Object();
    static int counter = 0;
    public static void main(String[] args) {
        synchronized (lock) {
            counter++;
        }
    }
}

圖片圖片

  • monitorenter: 上鎖開始的地方
  • monitorexit:  解鎖的地方
  • 其中被monitorenter和monitorexit包圍住的指令就是上鎖的代碼

思考:為什么會出現兩個monitorexit

有兩個monitorexit的原因,第二個monitorexit是為了防止鎖住的代碼拋異常后不能及時釋放鎖在使用了synchornized代碼塊時需要指定一個對象,所以synchornized也被稱為對象鎖

monitor主要就是跟這個對象產生關聯,如下圖

圖片圖片

Monitor內部具體的存儲結構:

  • Owner:存儲當前獲取鎖的線程的,只能有一個線程可以獲取
  • EntryList:關聯沒有搶到鎖的線程,處于Blocked狀態的線程
  • WaitSet:關聯調用了wait方法的線程,處于Waiting狀態的線程

具體的流程:

  • 代碼進入synchorized代碼塊,先讓lock(對象鎖)關聯的monitor,然后判斷Owner是否有線程持有
  • 如果沒有線程持有,則讓當前線程持有,表示該線程獲取鎖成功
  • 如果有線程持有,則讓當前線程進入entryList進行阻塞,如果Owner持有的線程已經釋放了鎖,在EntryList中的線程去競爭鎖的持有權(非公平)
  • 如果代碼塊中調用了wait()方法,則會進去WaitSet中進行等待

3.面試題

面試官:synchronized關鍵字的底層原理?

  • Synchronized【對象鎖】
  • 采用互斥的方式讓同一時刻至多只有一個線程能持有【對象鎖】
  • 它的底層由monitor實現的,monitor是jvm級別的對象( C++實現),線程獲得鎖需要使用對象(鎖)關聯monitor
  • 在monitor內部有三個屬性,分別是owner、entrylist、waitset
  • 其中owner是關聯的獲得鎖的線程,并且只能關聯一個線程;entrylist關聯的是處于阻塞狀態的線程;waitset關聯的是處于Waiting狀態的線程
責任編輯:武曉燕 來源: springboot葵花寶典
相關推薦

2019-12-20 15:19:41

Synchroinze線程安全

2021-01-12 09:22:18

Synchronize線程開發技術

2024-11-20 15:55:57

線程Java開發

2021-03-10 15:59:39

JavaSynchronize并發編程

2022-01-26 00:03:00

關鍵字線程JVM

2009-08-12 13:37:01

Java synchr

2017-05-27 20:59:30

Java多線程synchronize

2021-08-15 08:11:54

AndroidSynchronize關鍵字

2021-01-08 08:34:09

Synchronize線程開發技術

2022-12-26 09:27:48

Java底層monitor

2009-06-29 18:26:11

Java多線程Synchronize同步類

2011-03-09 14:36:44

synchronizevolatile

2022-11-12 18:32:50

Golangomitemptyjson

2022-02-17 08:31:38

C語言staic關鍵字

2021-02-01 13:10:07

Staticc語言UNIX系統

2025-01-09 10:30:40

2022-05-06 08:32:40

Pythonwith代碼

2023-05-15 09:39:10

Java監視器鎖

2009-08-21 14:58:56

C# this關鍵字

2018-04-20 15:56:09

Pythonglobal關鍵字
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩国产精品一区 | 国产国产精品久久久久 | 日干夜干 | 国产精品久久久久久久久久免费看 | 久久久精品国产 | 久久久久久久久久久蜜桃 | 成人免费看片 | 久久久精品一区 | 91超碰在线观看 | 国产精品精品久久久 | 色成人免费网站 | 欧美精品网站 | 在线视频国产一区 | 久久久久亚洲 | 美女黄18岁以下禁止观看 | 中文字幕视频一区 | 日本午夜在线视频 | 亚洲一区二区在线播放 | 国产一区在线免费 | 成人午夜影院 | 永久看片 | 成人精品一区二区三区中文字幕 | 99精品亚洲国产精品久久不卡 | 亚洲欧美在线免费观看 | 欧美性吧 | www.亚洲成人网 | 成人在线中文字幕 | 九九热国产视频 | 国产精品视频免费观看 | 91免费看片| 亚洲不卡 | 日韩国产精品一区二区三区 | 亚洲黄色av | 一区二区三区四区在线视频 | 久久久精品高清 | 午夜成人在线视频 | 欧美高清视频一区 | 国产精品99免费视频 | av网站在线播放 | 日韩在线不卡 | 黄色大片免费网站 |