<JavaEE> 鎖進階 -- synchronized 的鎖優化

目錄

一、如何形容 synchronized 鎖

二、鎖升級

2.1 偏向鎖

2.2 輕量級鎖

2.3 重量級鎖

三、鎖消除

四、鎖粗化


一、如何形容 synchronized 鎖

synchronized 鎖是一個內部優化非常好的鎖,大部分情況下這個鎖都是適用的。
在初始階段 synchronized 是一個樂觀鎖、輕量級鎖、自旋鎖,隨著鎖沖突變得更激烈,synchronized 會轉換為悲觀鎖、重量級鎖、掛起等待鎖。

與此同時,synchronized 還是一個可重入鎖、非公平鎖、非讀寫鎖。


二、鎖升級

synchronized 的加鎖過程
無鎖偏向鎖輕量級鎖重量級鎖

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

JVM 將 synchronized 鎖分為 以上四個階段,會根據實際情況,對鎖進行升級。應該注意的是,目前所只能升級,不能降級。

2.1 偏向鎖

階段描述:
當鎖第一次被一個線程獲取時,優先進入偏向鎖狀態。
偏向鎖并非真的“加鎖”,而是在對象頭中做一個“偏向鎖標記”,記錄該鎖屬于哪個線程。
如果后續沒有其他線程競爭該鎖,那么該鎖不會有后續升級操作,減少了加鎖帶來的系統開銷。
如果后續有其他線程競爭該鎖,那么鎖會真正的加鎖,升級為輕量級鎖。由于之前已經記錄了該鎖屬于哪個線程,所以此時鎖也是被記錄的線程獲取的。
這種升級操作實際上屬于延遲加鎖,不必要不加鎖,減少了加鎖的系統開銷,提高了運行效率。

2.2 輕量級鎖

階段描述:
隨著鎖競爭的開始,鎖將進入輕量級鎖的狀態,在初始狀態是通過自旋鎖實現的。
自旋鎖是循環不斷地讓線程嘗試獲取鎖。優點在于當鎖被釋放,其他線程可以第一時間獲取到鎖。
而自旋鎖的缺點也在于會一直占用CPU資源。synchronized 對此也進行了優化,當自旋達到一定的時間或次數時,就不再自旋了,將轉換為掛起等待。
同時,synchronized 內部也會統計當前鎖對象有多少線程在競爭,如果鎖競爭更加激烈,synchronized 就會從輕量級鎖升級為重量級鎖。

2.3 重量級鎖

階段描述:
重量級鎖是指使用內核提供的 mutex 鎖。
mutex 鎖執行加鎖操作時,會先進入內核態,在內核態判定當前鎖是否已經被占用。
如果該鎖沒有被占用,則加鎖成功,并切換回用戶態。
如果該鎖已經被占用,則加鎖失敗,線程阻塞等待,直到下一次喚醒。

三、鎖消除

什么是鎖消除?
鎖消除是?synchronized 鎖的一種較保守的優化策略,通過編譯器和JVM判斷鎖是否可以消除。
這里的鎖消除只會處理一些直接可以判斷,完全不涉及線程安全問題的鎖,比如在單線程環境下使用 StringBuffer 類中的方法。

四、鎖粗化

什么是鎖粗化?
這里有一個鎖的粒度的概念,可以這么認為:在鎖對象代碼塊中的代碼越少則認為鎖的粒度越細,反之則是越粗。
實際開發中,使用細粒度的鎖,往往是為了鎖可以被其他線程及時獲取。但有時,可能很長一段時間都沒用其他線程來競爭這個鎖。
因此,如果一段邏輯中出現多次加鎖解鎖,根據編譯器和JVM的判斷會自動對鎖進行粗化。
鎖粗化是指將多個細粒度的鎖合并為一個粗粒度的鎖,可以在特定場景下提高程序的執行效率,減小系統開銷。

閱讀指針 -> 《CAS編程及相關類》

鏈接生成中..........

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

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

相關文章

分布式搜索引擎02

分布式搜索引擎02 在昨天的學習中,我們已經導入了大量數據到elasticsearch中,實現了elasticsearch的數據存儲功能。但elasticsearch最擅長的還是搜索和數據分析。 所以今天,我們研究下elasticsearch的數據搜索功能。我們會分別使用DSL和Res…

react面試總結2

redux中sages和thunk中間件的區別,優缺點 Redux 中的 redux-saga 和 redux-thunk 都是中間件,用于處理異步操作,但它們有一些區別。 Redux Thunk: 簡單易用:redux-thunk 是比較簡單直觀的中間件,它允許 …

手撕分布式緩存---HTTP Server搭建

經過了前兩個章節的學習,分布式緩存的存儲與新增我們已經實現了,并且對其做了高可用處理。本章節我們剝離和緩存強相關的邏輯,開始搭建一個HTTP服務器,畢竟緩存數據庫搭建完之后別人沒法訪問也是沒有用處的。這一章節我們重點學習…

ElasticSearch應用場景以及技術選型[ES系列] - 第496篇

歷史文章(文章累計490) 《國內最全的Spring Boot系列之一》 《國內最全的Spring Boot系列之二》 《國內最全的Spring Boot系列之三》 《國內最全的Spring Boot系列之四》 《國內最全的Spring Boot系列之五》 《國內最全的Spring Boot系列之六》 M…

PDF控件Spire.PDF for .NET【轉換】演示:將 PDF 轉換為 Excel

PDF是一種通用的文件格式,但它很難編輯。如果您想修改和計算PDF數據,將PDF轉換為Excel將是一個理想的解決方案。在本文中,您將了解如何使用Spire.PDF for .NET在 C# 和 VB.NET 中將 PDF 轉換為 Excel。 Spire.Doc 是一款專門對 Word 文檔進行…

【華為數據之道學習筆記】3-10元數據管理架構及策略

元數據管理架構包括產生元數據、采集元數據、注冊元數據和運 維元數據。 產生元數據: 制定元數據管理相關流程與規范的落地方案,在IT產品開發過程中實現業務元數據與技術元數據的連接。 采集元數據: 通過統一的元模型從各類IT系統中自動采集元…

多線程(初階九:線程池)

目錄 一、線程池的由來 二、線程池的簡單介紹 1、ThreadPoolExecutor類 (1)核心線程數和最大線程數: (2)保持存活時間和存活時間的單位 (3)放任務的隊列 (4)線程工…

Axure的安裝以及簡單使用

目錄 Axure簡介 是什么 有什么用 Axure的優缺點 優點: 缺點: 安裝 漢化 Axure的使用 工具欄 頁面 ?編輯 添加子頁面 ?編輯 Axure簡介 是什么 Axure是一款著名的原型設計工具。它允許用戶創建交互式線框圖、流程圖、原型和其他設計文檔&…

「Verilog學習筆記」脈沖同步電路

專欄前言 本專欄的內容主要是記錄本人學習Verilog過程中的一些知識點,刷題網站用的是牛客網 timescale 1ns/1nsmodule pulse_detect(input clk_fast , input clk_slow , input rst_n ,input data_in ,output dataout );reg data_level, dat…

第十一章 React 封裝自定義組件

一、專欄介紹 🌍🌍 歡迎加入本專欄!本專欄將引領您快速上手React,讓我們一起放棄放棄的念頭,開始學習之旅吧!我們將從搭建React項目開始,逐步深入講解最核心的hooks,以及React路由、…

【NLP】RAG 應用中的調優策略

? 檢索增強生成應用程序的調優策略 沒有一種放之四海而皆準的算法能夠最好地解決所有問題。 本文通過數據科學家的視角審視檢索增強生成(RAG)管道。它討論了您可以嘗試提高 RAG 管道性能的潛在“超參數”。與深度學習中的實驗類似,例如&am…

關于jinja2高版本api變化導致notebook導出html失敗的問題

最新jinja2版本已經到了3.1.2,但是nbconvert引用的應該是老版本,具體代碼報錯如下 Type "help", "copyright", "credits" or "license" for more information. >>> import nbconvert Traceback (most…

spark從表中采樣(隨機選取)一定數量的行

在Spark SQL中,你可以使用TABLESAMPLE來按行數對表進行采樣。以下是使用TABLESAMPLE的示例: SELECT * FROM table_name TABLESAMPLE (1000 ROWS);在這個示例中,table_name是你要查詢的表名。TABLESAMPLE子句后面的(1000 ROWS)表示采樣的行數…

axios 基礎的 一次封裝 二次封裝

一、平常axios的請求發送方式 修改起來麻煩的一批 代碼一大串 二、axios的一次封裝 我們會在src/utils創建一個request.js的文件來存放我們的基地址與攔截器 /* 封裝axios用于發送請求 */ import axios from axios/* (1)request 相當于 Axios 的實例對象 (2)為什么要有reque…

VSCode使用Remote-SSH連接服務器時報錯:無法與“***”建立連接: XHR failed.

關于VSCode的報錯問題:無法與“***”建立連接: XHR failed 問題描述問題理解解決方法手動在本地下載安裝包,然后手動傳到服務器端 問題描述 是的,我又踩坑了,而且這個弄了好久,也重新裝了VSCode軟件,好像結…

2024黑龍江省職業院校技能大賽暨國賽選拔賽“GZ031應用軟件系統開發”賽項賽題題庫

2024黑龍江省職業院校技能大賽暨國賽選拔賽 “GZ031應用軟件系統開發”賽項賽題題庫 2024黑龍江省職業院校技能大賽暨國賽選拔賽 應用軟件系統開發賽項(高職組) 賽題第1套 目錄 競賽說明 模塊一:系統需求分析 任務1:制造執行…

Kotlin之for循環的具體使用說明

我們用java進行Android開發過程中,經常會用到for循環,在Kotlin中也會經常用到,但是在最近使用Kotlin中我發現,在java中使用for循環不會有什么問題,但是在Kotlin中會出現問題,就是循環出出來的結果不一樣&am…

前端框架(Front-end Framework)和庫(Library)的區別

聚沙成塔每天進步一點點 ? 專欄簡介 前端入門之旅:探索Web開發的奇妙世界 歡迎來到前端入門之旅!感興趣的可以訂閱本專欄哦!這個專欄是為那些對Web開發感興趣、剛剛踏入前端領域的朋友們量身打造的。無論你是完全的新手還是有一些基礎的開發…

阿里云國際版CDN加速,如何判斷網站IP已加速?

將源站接入阿里云CDN服務后,您可以通過IP檢測功能,檢測客戶端請求實際訪問的IP是否為CDN加速節點IP,判斷加速是否生效。 應用場景 IP檢測的應用場景如下: 場景一:成功配置CDN后,您可以檢測客戶端請求實際…

Android popupwindow在低版本手機上無法顯示

所以我開始看各個參數,注意到了在我自定義popupwindow的builder下的:👇👇 .showAsDropDown(mLinMain, 0, 0);就是這個,這時候我想到了屏幕的原點坐標是(0, 0),所設置的p…