在現(xiàn)實(shí)場(chǎng)景中,搶票代碼,如果不加鎖,就會(huì)出現(xiàn)超賣或者一張票賣給多個(gè)人
Synchronized對(duì)象鎖采用互斥的方式讓同一時(shí)刻至多只有一個(gè)線程能持有對(duì)象鎖,其它線程再想獲取這個(gè)對(duì)象鎖時(shí)就會(huì)阻塞住,代碼如下
public class synchronizedTest { // 創(chuàng)建一個(gè)靜態(tài)對(duì)象作為鎖 static Object lock = new Object(); // 初始票數(shù) int ticketNum = 20; // 獲取票的方法,使用 synchronized 修飾確保線程安全 public synchronized void getTicket() { // 使用當(dāng)前對(duì)象作為鎖 synchronized (this) { // 如果票數(shù)已經(jīng)為零,則返回 if (ticketNum <= 0) { return; } System.out.println(Thread.currentThread().getName() + "搶到一張票,剩余:" + ticketNum); // 非原子性操作,扣除一張票 ticketNum--; } } public static void main(String[] args) { // 創(chuàng)建 synchronizedTest 實(shí)例 synchronizedTest synchronizedTest = new synchronizedTest(); // 創(chuàng)建并啟動(dòng) 20 個(gè)線程 for (int i = 0; i < 20; i++) { // 調(diào)用獲取票的方法 new Thread(() -> synchronizedTest.getTicket()).start(); } }}通過以上代碼,加synchronized鎖,就可以防止超賣
特別說明:synchronized 關(guān)鍵字的底層實(shí)現(xiàn)涉及到 Java 虛擬機(jī)中的監(jiān)視器(Monitor)機(jī)制。每個(gè) Java 對(duì)象都與一個(gè) Monitor 相關(guān)聯(lián),Monitor 負(fù)責(zé)對(duì)象的鎖定和解鎖,以及線程的阻塞和喚醒。
Monitor 被翻譯為監(jiān)視器,是由jvm提供,c++語言實(shí)現(xiàn)
使用一下簡(jiǎn)單代碼中查看monitor,通過javap命令查看clsss的字節(jié)碼
public class MonitorTest { static final Object lock = new Object(); static int counter = 0; public static void main(String[] args) { synchronized (lock) { counter++; } }}
圖片
思考:為什么會(huì)出現(xiàn)兩個(gè)monitorexit
有兩個(gè)monitorexit的原因,第二個(gè)monitorexit是為了防止鎖住的代碼拋異常后不能及時(shí)釋放鎖在使用了synchornized代碼塊時(shí)需要指定一個(gè)對(duì)象,所以synchornized也被稱為對(duì)象鎖
monitor主要就是跟這個(gè)對(duì)象產(chǎn)生關(guān)聯(lián),如下圖
圖片
Monitor內(nèi)部具體的存儲(chǔ)結(jié)構(gòu):
具體的流程:
面試官:synchronized關(guān)鍵字的底層原理?
- Synchronized【對(duì)象鎖】
- 采用互斥的方式讓同一時(shí)刻至多只有一個(gè)線程能持有【對(duì)象鎖】
- 它的底層由monitor實(shí)現(xiàn)的,monitor是jvm級(jí)別的對(duì)象( C++實(shí)現(xiàn)),線程獲得鎖需要使用對(duì)象(鎖)關(guān)聯(lián)monitor
- 在monitor內(nèi)部有三個(gè)屬性,分別是owner、entrylist、waitset
- 其中owner是關(guān)聯(lián)的獲得鎖的線程,并且只能關(guān)聯(lián)一個(gè)線程;entrylist關(guān)聯(lián)的是處于阻塞狀態(tài)的線程;waitset關(guān)聯(lián)的是處于Waiting狀態(tài)的線程
本文鏈接:http://m.www897cc.com/showinfo-26-76499-0.htmlSynchronized關(guān)鍵字的底層原理?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 記一次 .NET某設(shè)備監(jiān)控自動(dòng)化系統(tǒng) CPU爆高分析
下一篇: 深入理解Java淺拷貝與深拷貝