日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java并发之synchronized实现原理及其优化

發布時間:2023/12/4 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java并发之synchronized实现原理及其优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1:synchronnized概述

synchronized修飾的方法或代碼塊相當于并發中的臨界區,即在同一時刻jvm只允許一個線程進入執行。synchronized是通過鎖機制實現同一時刻只允許一個線程來訪問共享資源的。另外synchronized鎖機制還可以保證線程并發運行的原子性,有序性,可見性。

2:synchronized的實現原理

Monitor被翻譯為監視器或管程
每個Java對象都可以關聯一個Monitor對象,如果使用synchronized給對象上鎖(重量級)之后,該對象頭的Mark Word中就被設置指向Monitor對象的指針

剛開始Monitor中Owner為null當Thread-2執行synchronized(obj)就會將Monitor的所有者Owner置為Thread-2,Monitor中只能有一個Owner
在Thread-2上鎖的過程中,如果Thread-3,Thread-4,Thread-5也來執行synchronized(obj),就會進入EntryList BLOCKED
Thread-2執行完同步代碼塊的內容,然后喚醒EntryList中等待的線程來競爭鎖,競爭的時是非公平的
注意
synchronized必須是進入同一個對象的monitor才有上述的效果
不加synchronized的對象不會關聯監視器,不遵從以上規則

3:為什么要對synchronized進行優化

Synchronized是通過對象內部的一個叫做監視器鎖(monitor)來實現的。但是監視器鎖本質又是依賴于底層的操作系統的Mutex Lock來實現的。而操作系統實現線程之間的切換就需要從用戶態轉換到核心態,這個成本非常高,狀態之間的轉換需要相對比較長的時間,這就是為什么Synchronized效率低的原因。因此,這種依賴于操作系統Mutex Lock所實現的鎖我們稱之為“重量級鎖”。
在jdk1.5之前,只有synchronized重量級鎖,實現需要借助操作系統,是比較消耗性能的操作,在1.6之中為了提高性能,便對synchronized鎖進行了優化,實現了各種鎖優化技術,如:適應性自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖。

4:輕量級鎖

(1):是什么
輕量級鎖是jdk1.6中加入的新型鎖機制,它名字中的“輕量級”是相對于使用操作系統互斥量來實現的重量級鎖而言的。首先需要強調的是,輕量級鎖并不是來代替重量級鎖的,它的本意是在沒有多線程競爭的前提下,減少傳統重量級鎖使用操作系統互斥量產生的性能消耗。在解釋輕量級鎖的執行過程之前,先明白一點,輕量級鎖所適應的場景是線程交替執行同步塊的情況,如果存在同一時間訪問同一鎖的情況,就會導致輕量級鎖膨脹為重量級鎖。
(2):上鎖的過程
 - 在輕量級鎖的執行過程上,在代碼進入同步塊的時候,如果此同步對象沒有被鎖定,也就是說此時對象的鎖標記位為“01”狀態,那么虛擬機首先將在線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,內部可以儲存鎖定對象的MarkWord。

  • 然后虛擬機將使用CAS操作嘗試將棧幀中的Lock Record更新為指向該對象的Mark Word的指針,如果這個更新動作成功了,那么這個線程就擁有了該對象的鎖,并且對象Mark Word的鎖標志位將轉變位00,即表示此對象處于輕量級鎖定狀態,

  • 如果cas操作更新失敗的話

  • 對比重量級別的鎖:
    如果線程之間不存在鎖的競爭,與重量級鎖相比,輕量級鎖避免使用了互斥信號量,只使用了簡單的CAS操作,但如果存在鎖競爭,輕量級鎖除了使用互斥信號量,還要額外發生CAS操作,因此在有競爭的情況下,輕量級鎖會比重量級鎖開銷更大。

5:鎖膨脹

(1):是什么
如果在嘗試加輕量級鎖的過程中,CAS操作無法成功,這時一種情況就是有其它線程為此對象加上了輕量級鎖(有競爭),這時需要進行鎖膨脹,將輕量級鎖變為重量級鎖。

(2):如何形成的

那么當Thread-0去使用CAS去解鎖的時候,就不能按原先的步驟進行了,因為現在的鎖為重量級鎖

6:自旋鎖

自旋鎖原理非常簡單,如果持有鎖的線程能在很短時間內釋放鎖資源,那么那些等待競爭鎖的線程就不需要做內核態和用戶態之間的切換進入阻塞掛起狀態,它們只需要等一等(自旋),等持有鎖的線程釋放鎖后即可立即獲取鎖,這樣就避免用戶線程和內核的切換的消耗。但是線程自旋是需要消耗cpu的,說白了就是讓cpu在做無用功,如果一直獲取不到鎖,那線程也不能一直占用cpu自旋做無用功,所以需要設定一個自旋等待的最大時間。
如果持有鎖的線程執行的時間超過自旋等待的最大時間仍沒有釋放鎖,這時其他爭用線程會停止自旋進入阻塞狀態。

7:偏向鎖

(1):是什么

Java偏向鎖是在jdk1.6中引入的,它的目的是消除數據無競爭情況下的同步原語,進一步提高程序的運行性能。如果說輕量級鎖是在無競爭的情況下使用CAS操作去消除同步使用的互斥量,那偏向鎖就是在無競爭的情況下把整個同步都消除連CAS都不做。
偏向鎖,顧名思義,它會偏向于第一個訪問它的線程,如果在運行過程中,同步鎖只有一個線程訪問,不存在多線程爭用鎖的情況,則持有偏向鎖的線程將永遠是不需要在進行同步。
如果運行過程中,遇到其它線程搶占資源,則持有偏向鎖的線程會被掛起,jvm會消除它身上的偏向鎖,將鎖恢復到標準的輕量級鎖。

(2):為什么不直接使用輕量級鎖

引入偏向級鎖是為了減少在無多線程競爭的情況下,盡量減少不必要的輕量級鎖執行路徑。
因為輕量級鎖的獲取及釋放依賴多次CAS原子指令,而偏向鎖只需要在置換線程時,使用CAS操作把獲取到這個鎖的線程線程的ID記錄在對象的Mark Word之中,從而減少性能消耗,不過遇到多線程競爭的情況時就必須撤銷偏向鎖。
另外一個原因就是,在虛擬機中,大多時候是不存在鎖競爭的,常常是一個線程多次獲取同一個鎖,因此直接使用輕量級鎖會增加很多不必要的消耗,所以可以才引入了偏向鎖。

(3):偏向鎖的使用背景

偏向鎖可以提高帶有同步但無競爭的程序性能。但是如果程序中大多數鎖總是被多個不同的線程訪問,那么偏向鎖模式就是多余的。

7:總結

總結

以上是生活随笔為你收集整理的java并发之synchronized实现原理及其优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。