synchronized 的使用和特性

synchronized 鎖對象

普通方法
synchronized 鎖普通方法時,其鎖的對象是調用該方法的實例

public synchronized void method() {  // 方法體  
}  

靜態方法
靜態方法的鎖對象是所屬的 class,全局只有一個。

public static synchronized void staticMethod() {  // 方法體  
}  

同步代碼塊
鎖對象為括號內的指定對象。

synchronized(this) {  // 代碼塊  
}  

synchronized 特性

有序性
讀讀,讀寫,寫讀,寫寫互斥。

可見性
可見性是指多個線程訪問一個資源時,該資源的狀態,值等對于其他線程都是可見的。synchronized 和 volatile 都具有可見性,其中 synchronized 對一個類或對象加鎖時,一個線程如果要訪問該累或對象必須先獲得它的鎖。這個鎖的狀態對于其他任何線程都是可見的,并且在釋放鎖之前會將對變量的修改刷新到共享內存中,保證資源變量的可見性。

原子性
原子性指的是同一時間只有一個線程去執行代碼,該操作是不能被其他線程打斷的,那么就具備了原子性。

synchronized的原子性本質上是線程互斥保證的原子性。

可重入性
同一線程在持有鎖的情況下,可多次獲取同一鎖而不會導致死鎖或阻塞其他線程。這種機制通過維護鎖的持有計數器實現,當線程首次獲取鎖時計數器設為1,每次重入增加計數,釋放時減少計數,直到歸零才釋放鎖。

synchronized 鎖升級的對象頭內容:
在這里插入圖片描述

偏向鎖的意義和使用前提

偏向鎖就是在運行過程中,對象的鎖偏向某個線程。即在開啟偏向鎖機制的情況下,某個線程獲得鎖,當該線程下次再想要獲得鎖時,不需要重新申請獲得鎖(即忽略synchronized關鍵詞),直接就可以執行同步代碼,比較適合競爭較少的情況。

JDK 1.8 下加鎖會默認開啟偏向鎖。但是它在應用程序啟動幾秒后才會開啟,是存在延遲啟動的情況。因此可能在打印輸出加鎖時的信息會發現不符合偏向鎖的鎖標志。

當我們開啟了偏向鎖,并且沒有延遲開啟的時候,新創建的對象的 mark word 默認就是偏向鎖狀態的 markWord,只不過這個時候,因為沒有線程爭搶鎖,除了我們的鎖標志位和是否為偏向鎖標志位,其他都是 0

延遲的關閉和偏向鎖的關閉

延遲是可以關閉的。可以給 JVM 設置參數:-XX:BiasedLockingStartupDelay=0 來關閉延遲。
如果希望關閉偏向鎖:-XX:-UseBiasedLocking=false

偏向鎖細節

無鎖狀態下的 MarkWord 標志(看第一行的二進制數字):
01 表示偏向鎖,是由于開啟偏向鎖且沒有延遲開啟的情況下會顯示的,但是此時并沒有線程爭奪鎖。因此其他位置都是 0 ,僅僅是鎖標志位和是否為偏向鎖標志位有變化。
在這里插入圖片描述
線程加上偏向鎖后:
根據上圖,偏向鎖加上了后會有標識線程 ID,Epoch 等信息,因此不全是 0 。
在這里插入圖片描述

如果我們在加鎖前調用 hashcode 方法,會導致后續加鎖后變為輕量級鎖。

原理:

  • 被加鎖的對象,沒有真正調用或者隱式的調用(比如使用 HashMap 放入當前對象,會調用 HashCode 方法)父類 Object 的 hashCode 方法,如果一旦調用了 hashCode 方法,對象頭里需要有一個存儲該 hashCode 值的位置。但是我們可以從上圖中看到,偏向鎖中并沒有地方進行 MarkWord 的保存,只有輕量級鎖才會有。

  • 為了讓線程獲得鎖的代價更低而引入了偏向鎖。當一個線程訪問同步塊并獲取鎖時,會在對象頭和棧幀中的鎖記錄里存儲鎖偏向的線程ID(對象頭:存儲線程 ID,棧幀的鎖記錄中:線程有自己的棧幀,LOCK RECORD: 存儲當前線程 ID),以后該線程在進入和退出同步塊時不需要進行CAS操作來加鎖和解鎖,只需簡單地測試一下對象頭的Mark Word里是否存儲著指向當前線程的偏向鎖。(是否是當前線程的偏向鎖是通過ID來匹配的)

  • 如果測試成功,表示線程已經獲得了鎖。

  • 如果測試失敗,則需要再測試一下Mark Word中偏向鎖的標識是否設置成1(表示當前是偏向鎖):如果沒有設置,則使用CAS競爭鎖;如果設置了,則嘗試使用CAS將對象頭的偏向鎖指向當前線程(CAS 競爭,替換線程 ID)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90317.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90317.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90317.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gin Web 層集成 Viper 配置文件和 Zap 日志文件指南(下)

在微服務架構中,Gin 常被用作 Web 層框架,而 Viper 用于管理配置文件,Zap 則提供高性能的日志記錄功能。下面將詳細介紹如何在 Gin Web 層集成 Viper 配置文件和 Zap 日志文件。 1. 項目概述 假設我們有一個基于 Go 語言的微服務項目&#…

IoTDB:專為物聯網場景設計的高性能時序數據庫

什么是IoTDB?IoTDB(Internet of Things Database)是一款開源的時序數據庫管理系統,專為物聯網(IoT)場景設計,由清華大學軟件學院團隊自研,天謀科技團隊負責維護。它針對物聯網數據的…

[netty5: MessageAggregator HttpObjectAggregator]-源碼解析

在閱讀這篇文章前,推薦先閱讀 [netty5: ByteToMessageCodec & MessageToByteEncoder & ByteToMessageDecoder]-源碼分析[netty5: HttpObject]-源碼解析 100-continue 100-continue 是 HTTP/1.1 協議中的一種機制,用于客戶端在發送大體積請求體…

前端學習1--行內元素 vs 塊級元素(基礎概念+案例實操)

一、內外邊距學習:(1)簡單理解:padding為內邊距。padding不會影響元素的位置,只會調整元素的內容(文字)與邊框之間的間距。margin為外邊距。margin會影響元素在流式布局中的位置,改變…

Express + mysql2 + jwt 實現簡單的登錄鑒權

目前項目中使用Express 實現簡單API功能,需要提供一套登錄鑒權方案。這邊是API側實現 相關路由的登錄鑒權。大體思路:就是,登錄接口中通過jwt加密 token返回前端,前端其他接口把加密好的放入請求頭Authorization中。中間件通過請求…

ReAct (Reason and Act) OR 強化學習(Reinforcement Learning, RL)

這個問題觸及了現代AI智能體(Agent)構建的兩種核心思想。 簡單來說,ReAct 是一種“調用專家”的模式,而強化學習 (RL) 是一種“從零試錯”的模式。 為了讓你更清晰地理解,我們從一個生動的比喻開始,然后進行…

iTwinjs 4.10-4.11 更新

撤銷更改 目前,撤銷一個有缺陷的變更集的唯一方法是從 iModel Hub 中移除它,這可能會導致許多副作用(無法撤銷)。一個更好的方法是在時間線中撤銷變更集,并將其作為新的變更集引入。盡管這種方法仍然具有侵入性&#…

【CSS-15】深入理解CSS transition-duration:掌握過渡動畫的時長控制

在現代網頁設計中,平滑的過渡效果是提升用戶體驗的關鍵因素之一。CSS transitions 為我們提供了一種簡單而強大的方式來實現元素在不同狀態之間的平滑過渡,而 transition-duration 屬性則是控制這些過渡效果時長的核心工具。本文將全面探討 transition-d…

mysql-筆記

1. 安裝mysql # 使用brew安裝 brew install mysql# 查看是否安裝成功 mysql -V 相關文檔: mac:macOS下MySQL 8.0 安裝與配置教程 - KenTalk - 博客園 Linux安裝:linux安裝mysql客戶端_linux mysql 客戶端-CSDN博客 2. 啟動mysql 每次使…

Spring Boot啟動優化7板斧(延遲初始化、組件掃描精準打擊、JVM參數調優):砍掉70%啟動時間的魔鬼實踐

Spring Boot啟動優化7板斧:砍掉70%啟動時間的魔鬼實踐1. 延遲初始化:按需加載的智慧2. 組件掃描精準打擊:告別無差別掃描3. JVM參數調優:啟動加速的隱藏開關4. 自動配置瘦身:砍掉Spring Boot的"贅肉"5. 類加…

從0開始學習計算機視覺--Day08--卷積神經網絡

之前我們提到,神經網絡是通過全連接層對輸入做降維處理,將輸入的向量通過矩陣和激活函數進行降維,在神經元上輸出激活值。而卷積神經網絡中,用卷積層代替了全連接層。 不同的是,這里的輸入不再需要降維,而…

解決阿里云ubuntu內存溢出導致vps死機無法訪問 - 永久性增加ubuntu的swap空間 - 阿里云Linux實例內存溢出(OOM)問題修復方案

效果圖報錯通過對實例當前截屏的分析發現,實例因 Linux實例內存空間不足,導致操作系統出現內存溢出(OOM) 無法正常啟動。請您根據 Code:1684829582,在文檔中查詢該問題對應的修復方案,并通過VNC…

Serverless JManus: 企業生產級通用智能體運行時

作者:叢霄、陸龜 概述:本文介紹如何使用 JManus 框架構建通用智能體應用,部署并運行在 Serverless 運行時,構建企業級高可用智能體應用的實踐經驗。基于阿里云 Serverless 應用引擎SAE 運行穩定高可用的智能體應用, 基…

MySQL的數據目錄

導讀:根據前面的所學知識,我們知道了InnoDB存儲引擎存儲數據的數據結構、存儲過程,而被組織好的數據則被存儲在操作系統的磁盤上,當我們在對表數據進行增刪改查時,其實就是InnoDB存儲引擎與磁盤的交互。此外&#xff0…

Web前端開發: :has功能性偽類選擇器

:has功能性偽類選擇器::has() 是 CSS 中的一個功能性偽類選擇器,它允許開發者根據元素的后代元素、兄弟元素或后續元素的存在或狀態來選擇目標元素。它本質上是一個“父選擇器”或“關系選擇器”,解決了 CSS 長期以來無法根據子元素反向選擇父元素的痛點…

深度學習8(梯度下降算法改進2)

目錄 RMSProp 算法 Adam算法 學習率衰減 RMSProp 算法 RMSProp(Root Mean Square Prop)算法是在對梯度進行指數加權平均的基礎上,引入平方和平方根。 其中e是一個非常小的數,防止分母太小導致不穩定,當 dw 或 db 較大時,(du)2,(db)2會較大&…

JAVA面試寶典 -《網絡編程核心:NIO 與 Netty 線程模型詳解》

網絡編程核心:NIO 與 Netty 線程模型詳解 文章目錄網絡編程核心:NIO 與 Netty 線程模型詳解一、傳統 BIO 模型:排隊買奶茶的阻塞模式 🥤1.1 專業解釋1.2 簡單點比喻1.3 簡單示例二、NIO 模型:智能叫號餐廳系統 &#x…

藍橋杯 第十六屆(2025)真題思路復盤解析

本文以洛谷平臺所提供的題目描述及評測數據為基礎進行講解。 前言:這是本人的藍橋杯試卷,大概排省一前40%的位置,實際上這屆題目偏難,我沒有做出太多的有效得分。我把當時的思路和現在學習的思路都復盤進來,希望給大家…

蘭頓螞蟻路徑lua測試

蘭頓螞蟻local p0 local x,y,z0,7,0 local function add() local result,id Block:getBlockID(x,y,z)if id1 thenBlock:destroyBlock(x,y,z,false) pp90 elseBlock:setBlockAll(x,y,z,1,0) pp-90 end x,zx-math.floor(0.5math.sin(math.rad(p))),z-math.floor(0.5math.cos(m…

【Axure RP】什么是Axure?Axure可以用來做什么?

【Axure RP】什么是Axure?Axure可以用來做什么? 目錄【Axure RP】什么是Axure?Axure可以用來做什么?Axure RP簡介Axure RP 是什么?Axure RP核心功能和應用場景Axure RP簡介 Axure RP 是什么? Axure RP 是一…