有人說:輕量級鎖一定比重量級鎖快!我忍不住笑了

2021-02-23 Java中文社群

世界上不止有黑白兩色,黑與白之間還是灰色的地帶。

在成人的世界裡,大多數人喜歡非黑即白的觀點來看待一個問題,例如《十二公民》中那個剛開始所有人都認定的「一定是富二代殺S了自己的親身父親」,到最後大家理性分析和推測之後發現,事情根本不是大多數人(99.9%)以為的那樣。

我們很容易被他人的說辭所誤導,相信我們願意相信的事,聽我們願意聽的事,然後被輿論所支配,在人云亦云之中漸漸的迷失自我,然後喪失自己獨立思考的能力。

學技術也是一樣,盡信書不如無書,思考才是學習的目的,如果讀書不是為了啟迪自己的智慧,只是為了吹NB,那這個人有很大的概率會一事無成。

那此時我們再回過頭來思考這個問題:輕量級鎖一定比重量級鎖快嗎

正文

在回答這個問題之前,我們先來了解一下:什麼是輕量級鎖?什麼是重量級鎖?

鎖概念

輕量級鎖是 JDK 1.6 新增的概念,是相對於傳統的重量級鎖而已的一種狀態,在 JDK 1.5 時,synchronized 是需要通過作業系統自身的互斥量(mutex lock)來實現,然而這種實現方式需要通過用戶態與和核心態的切換來實現,但這個切換的過程會帶來很大的性能開銷,所以在 JDK 1.6 就引入了輕量級鎖來避免此問題的發生。

輕量級鎖執行過程

再講輕量級鎖執行過程之前,要先從虛擬機的對象頭開始說起,HotSpot 的對象頭(Object Header)分為兩部分

Mark Word 區域,用於存儲對象自身的運行時數據,如哈希碼(HashCode)、GC 分帶年齡等;用於存儲指向方法區對象類型數據的指針(如果是數組對象的話,還有一個存儲數組長度的額外信息)。

Mark Word 在 32 位系統中,有 32bit 空間,其中:

2bit 用來存儲鎖標誌位,01=可偏向鎖、00=輕量級鎖、10=重量級鎖;

再說會輕量級鎖的執行過程,在代碼進入同步塊的時候,如果此對象沒有被線程所佔用,虛擬機會先將此線程的棧幀拷貝一份存儲在當前對象的 Lock Record (鎖記錄) 區域中。

然後虛擬機再使用 CAS (Compare and Swap, 比較並交換) 將本線程的 Mark Word 更新為指向對象 Lock Record 區域的指針,如果更新成功,則表示這個線程擁有了該對象,輕量級鎖添加成功,如果更新失敗,虛擬機會先檢查對象 Mark Word 是否指向了當前線程的線幀,如果是則表明此線程已經擁有了此鎖,如果不是,則表明該鎖已經被其他線程佔用了。如果有兩條以上的線程在爭搶死鎖,那麼鎖就會膨脹為重量鎖,Mark Word 中存儲的就是指向重量級鎖的互斥量指針,後面等待鎖的線程也會進入阻塞狀態。

從以上的過程,我們可以看出輕量級鎖可以理解為是通過 CAS 實現的,理想的情況下是整個同步周期內不存在鎖競爭,那麼輕量鎖可以有效的提高程序的同步性能,然而,如果情況相反,輕量級鎖不但要承擔 CAS 的開銷還要承擔互斥量的開銷,這種情況下輕量級鎖就會比重量級鎖更慢,這就是我們本文的答案。

總結

輕量級鎖不是在任何情況下都比重量級鎖快的,要看同步塊執行期間有沒有多個線程搶佔資源的情況,如果有,那麼輕量級線程要承擔 CAS + 互斥量鎖的性能消耗,就會比重量鎖執行的更慢

關於好與壞和對於錯也是這個道理,有些事今天可能是對的,但明天有可能成錯的了。比如 JDK 1.5 時,你可以說同步線程只有一個方式:synchronized,然而 JDK 1.6 時又添加了 Lock。你昨天說的對的話,在明天可能就變成錯的了。所以對和錯其實並不是那麼絕對,它也沒那麼重要,重要的是你得有獨立思考的能力和辨識對錯認知。

朕已閱 

相關焦點

  • 淺談偏向鎖、輕量級鎖、重量級鎖
    為了換取性能,JVM在內置鎖上做了非常多的優化,膨脹式的鎖分配策略就是其一。理解偏向鎖、輕量級鎖、重量級鎖的要解決的基本問題,幾種鎖的分配和膨脹過程,有助於編寫並優化基於鎖的並發程序。「鎖的持有時間比較短」這一條件可以放寬。實際上,只要鎖競爭的時間比較短(比如線程1快釋放鎖的時候,線程2才會來競爭鎖),就能夠提高自旋獲得鎖的概率。這通常發生在鎖持有時間長,但競爭不激烈的場景中。
  • JAVA對象分析之偏向鎖、輕量級鎖、重量級鎖升級過程
    如果進入輕量級鎖或者重量級鎖,意味著會用30bit指向指針,那麼此時對象頭中就只有兩種信息,鎖標誌、指向鎖的指針。其中無鎖和偏向鎖的鎖標誌位都是01,只是在前面的1bit區分了這是無鎖狀態還是偏向鎖狀態。JDK1.6以後的版本在處理同步鎖時存在鎖升級的概念,JVM對於同步鎖的處理是從偏向鎖開始的,隨著競爭越來越激烈,處理方式從偏向鎖升級到輕量級鎖,最終升級到重量級鎖。
  • 死磕Synchronized底層實現--重量級鎖
    本系列文章將對HotSpot的synchronized鎖實現進行全面分析,內容包括偏向鎖、輕量級鎖、重量級鎖的加鎖、解鎖、鎖升級流程的原理及源碼分析,希望給在研究synchronized路上的同學一些幫助。
  • Java 中15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等
    介紹的內容如下:1.公平鎖 / 非公平鎖2.可重入鎖 / 不可重入鎖3.獨享鎖 / 共享鎖4.互斥鎖 / 讀寫鎖5.樂觀鎖 / 悲觀鎖6.分段鎖7.偏向鎖 / 輕量級鎖 / 重量級鎖8.自旋鎖上面是很多鎖的名詞,這些分類並不是全是指鎖的狀態,有的指鎖的特性,有的指鎖的設計,下面總結的內容是對每個鎖的名詞進行一定的解釋
  • 大話Synchronized及鎖升級
    ,引入了偏向鎖、輕量級鎖的概念。因此大家會發現在 synchronized 中,鎖存在四種狀態分別是:無鎖、偏向鎖、輕量級鎖、重量級鎖;我們知道synchronized鎖的是對象,對象就是Object,Object在heap中的布局,如下圖所示
  • 「從入門到放棄-Java」並發編程-鎖-synchronized
    synchronized有四種狀態:無鎖 -> 偏向鎖 -> 輕量級鎖 -> 重量級鎖。無鎖沒有對資源進行鎖定,所有線程都能訪問和修改。自旋一定次數或有新的線程來競爭鎖時,輕量級鎖膨脹為重量級鎖。CASCAS即compare and swap(比較並替換)。是一種樂觀鎖機制。
  • 面試官經常問的synchronized實現原理和鎖升級過程,你真的了解嗎
    注意JDK1.6之前只有重量級鎖的,JDK1.6之後才有了偏向鎖和輕量級鎖,後面鎖升級部分會詳細講解。JDK1.6之前synchronized使用的是重量級鎖,JDK1.6之後進行了優化,擁有了無鎖->偏向鎖->輕量級鎖->重量級鎖的升級過程,而不是無論什麼情況都使用重量級鎖。
  • 源碼時代java小課堂之線程鎖之自旋鎖
    自旋鎖是基於CAS實現2. synchronized重量級鎖是基於系統內核3.為什麼出現自旋鎖jvm發現一個問題,多個線程共享資源的時間片段是及其短暫的,如果為了這點時間片段,我們採用基於系統內核的重量級鎖,不斷的,掛起線程,喚醒線程是極度的消耗資源的,於是我們就想到,如果那個線程持有共享資源的鎖,誰就執行,但是如果有多個線程同時需要執行共享資源呢,自旋鎖誕生了這裡對於自旋鎖和系統重量級鎖,我們來舉一個示例說明
  • 24張圖帶你徹底理解Java中的21種鎖
    Java 在線文檔、 Github。、reentrantlock(false)8共享鎖ReentrantReadWriteLock中讀鎖9獨佔鎖synchronized、vector、hashtable、ReentrantReadWriteLock中寫鎖10重量級鎖synchronized11輕量級鎖鎖優化技術12偏向鎖鎖優化技術13分段鎖concurrentHashMap14互斥鎖synchronized15同步鎖synchronized16
  • 不懂什麼是 Java 中的鎖?看看這篇你就明白了!
    Java 鎖分類Java 中的鎖有很多,可以按照不同的功能、種類進行分類,下面是我對 Java 中一些常用鎖的分類,包括一些基本的概述從線程是否需要對資源加鎖可以分為 悲觀鎖 和 樂觀鎖從資源已被鎖定,線程是否阻塞可以分為 自旋鎖從多個線程並發訪問資源,也就是 Synchronized 可以分為 無鎖、偏向鎖、 輕量級鎖和 重量級鎖
  • 「轉載」java架構之路(多線程)synchronized詳解以及鎖的膨脹升級...
    鎖的分類java中我們聽到很多的鎖,什麼顯示鎖,隱式鎖,公平鎖,重入鎖等等,下面我來總結一張圖來供大家學習使用。這次博客我們主要來說我們的隱示鎖,就是我們的無鎖到重量級鎖。從無鎖到重量級鎖的一個升級過程,我們來邊畫圖,邊詳細看一下。
  • Java鎖的那些事兒
    Java中的鎖機制主要分為 Lock和 Synchronized,本文主要分析Java鎖機制的使用和實現原理,按照Java鎖使用、JDK中鎖實現、系統層鎖實現的順序來進行分析,話不多說,let's go~一、Java鎖使用在Lock接口出現之前,Java程序是靠synchronized關鍵字實現鎖功能的,而JavaSE 5之後,並發包中新增了Lock接口(以及相關實現類)
  • 詳解鎖原理,synchronized、volatile+cas底層實現
    因為entryList的線程會先自旋嘗試加鎖,而不是加入cxq排隊等待,不公平3 Object的wait和notify方法原理wait,notify必須是持有當前對象鎖Monitor的線程才能調用 (對象鎖代指ObjectMonitor/Monitor,鎖對象代指Object)上面有說到,當在sychronized
  • 我的抽屜,你別開:易鎖寶智能抽屜鎖上手
    記得小時候家裡書桌有個神秘的帶鎖抽屜,每每家裡用錢的時候,老媽就會摸出一串鑰匙叮裡噹啷的讓人遐想,那個抽屜從不讓我碰,後來長到了才有機會一睹真容。其實就是個帶鎖的普通抽屜,不過裡面裝的是我們家最重要的東西。
  • 指紋鎖的這3個使用技巧,看懂後,玩轉指紋鎖不在話下
    通常菜單欄是需要輸入指定的命令進入,比如:0#、1#、*#等,不同品牌的指紋鎖,喚醒菜單的命令也會不一樣。輸入菜單命令之後就需要輸入管理員密碼。有人要問了,我剛裝上那裡會有管理員密碼?二、出門反鎖大部分人都會有出門反鎖的習慣,傳統的機械鎖反鎖是需要用鑰匙反轉兩圈,才能實現反鎖,指紋鎖就相對簡單的多。指紋鎖的反鎖只需要上提把手即可實現,有人會問:為什麼機械鎖一定要用鑰匙,指紋鎖只需要上提就可以了?
  • 誰動了我的摩託車鎖?
    我是一把安裝在一輛摩託車上的鎖,平凡的我發揮著不平凡的作用——車的啟動和防盜都離不開我。我的主人性情隨和,做事比較負責,他留平頭已經好多年了,我暗地裡稱呼他「平頭哥」。  六月的某一天,街口燈火通明,平頭哥下班了,他哼著歌曲正要啟動摩託車,然而,鑰匙卻無法與往常一樣使用,這鎖是怎麼啦?剛才還好好的,見鬼了!
  • 81歲老人收藏兩百多把銅鎖 對詩才能打開的鎖見過嗎
    有人喜歡古玩字畫,有人愛好錢幣瓷器。年長者可能喜歡集郵,年輕人可能喜歡收集球衣海報。有時候,收藏不僅是個人愛好的積累體現,還要考驗人們保存、維護的功力。81歲的杭州人吳兆申卻有一個獨特的愛好:他喜歡收藏舊鎖。
  • 共享鎖、排他鎖、互斥鎖、悲觀鎖、樂觀鎖、行鎖、表鎖、頁面鎖、不可重複讀、丟失修改、讀髒數據
    共享鎖(S鎖): 又稱為讀鎖,可以查看但無法修改和刪除的一種數據鎖。如果事務T對數據A加上共享鎖後,則其他事務只能對A再加共享鎖,不能加排它鎖。獲準共享鎖的事務只能讀數據,不能修改數據。 共享鎖下其它用戶可以並發讀取,查詢數據。但不能修改,增加,刪除數據。資源共享.
  • 我和面試官的博弈:Java 並發編程篇
    我們知道synchronized是悲觀鎖,一直以來被當做重量級鎖。但是jdk1.6對鎖進行了優化,比如**自旋鎖、適應性自旋鎖、鎖消除、偏向鎖以及輕量級鎖**等技術來減少鎖操作的開銷,這些你都了解嗎?我:知道一些。鎖主要存在四種狀態:無鎖狀態、偏向鎖狀態、輕量級鎖狀態、重量級鎖狀態。他們會隨著競爭的激烈而逐漸升級。
  • 說了都是淚 方正智能指紋鎖安裝體驗記
    先說為啥想換鎖,老爺子快70了,腿腳很利索,不過,問題是,耳背,我這個經常不帶鑰匙的人來說,那敲門就是一件非常痛苦的事兒。放眼一看,大多都是連APP的,真心想放棄的時候,看到了方正,北大方正出的東西,心想一定不會差了,看了一下網上店鋪,服務是到位,鎖有人換不說,還能免費先用30天,這先用後買,看得出來,方正對自家產品的信心是十足的呀。 買定離手,發貨也快,兩天到貨。找師傅,人家說,在外面忙,要等到後天才能安排。我這急性子,能等嗎?不就換個鎖嘛,自己動手,分分鐘搞定!