1. 程式人生 > >JAVA多執行緒之——自旋鎖、CLH、MCS

JAVA多執行緒之——自旋鎖、CLH、MCS

自旋鎖

學習瞭解自旋鎖之前先回顧一下互斥鎖
互斥鎖
執行緒在獲取互斥鎖的時候,如果發現鎖已經被其它執行緒佔有,那麼執行緒就會驚醒休眠,然後在適當的時機(比如喚醒)在獲取鎖。
自旋鎖
那麼自旋鎖顧名思義就是“自旋”。就是當一個執行緒在嘗試獲取鎖失敗之後,執行緒不會休眠或者掛起,而是一直在迴圈檢測鎖是否被其它執行緒釋放。
區別
互斥鎖就是開始開銷要大於自旋鎖。臨界區持鎖時間的大小並不會對互斥鎖的開銷造成影響,而自旋鎖是死迴圈檢測,加鎖全程消耗cpu,起始開銷雖然低於互斥鎖,但是隨著持鎖時間,加鎖的開銷是線性增長。
適用的情況
互斥鎖用於臨界區持鎖時間比較長的操作,比如下面這些情況都可以考慮

  • 臨界區有IO操作
  • 臨界區程式碼複雜或者迴圈量大
  • 臨界區競爭非常激烈
  • 單核處理器
    自旋鎖就主要用在臨界區持鎖時間非常短且CPU資源不緊張的情況下。當遞迴呼叫時有可能造成死鎖。
    執行緒(節點)佇列
    瞭解了自旋鎖之後,在學習ReentrantLock的時候,一個執行緒在等待鎖的時候會被封裝成一個Node節點,然後加入一個佇列中並檢測前一個節點是否是頭節點,並且嘗試獲取鎖,如果獲取鎖成功就返回,否則就阻塞。直到上一個節點釋放鎖並喚醒它。這樣看來似乎跟自旋沒什麼掛鉤。這是因為AQS裡面的CLH佇列是CLH佇列鎖的一種變形。先來了解一下CLH佇列鎖

CLH佇列鎖
CLH(Craig, Landin, and Hagersten locks): 是一個自旋鎖,能確保無飢餓性,提供先來先服務的公平性。
CLH鎖也是一種基於連結串列的可擴充套件、高效能、公平的自旋鎖,申請執行緒只在本地變數上自旋,它不斷輪詢前驅的狀態,如果發現前驅釋放了鎖就結束自旋。

http://www.2cto.com/kf/201412/363574.html這篇文章中有比較詳細的圖解。
AQS中的CLH佇列
瞭解了自旋鎖與CLH佇列鎖之後,在學習AQS中的CLH佇列就比較簡單了。AQS中的CLH佇列主要是對CLH佇列鎖改動了兩個地方
1.節點結構上做出改變。CLH佇列鎖的節點包含一個布林型別locked的欄位。如果要獲取鎖,就將這個locked設定為true。然後就不停的輪訓前驅節點的locked是否釋放了鎖(這個過程我們就叫做自旋)。AQS的CLH佇列在結構上引入了頭節點,尾節點。並且擁有一個前節點與下一個節點的引用。
2.在等待獲取鎖的機制上由自旋改成了等待阻塞。具體實現在
ReentrantLock:http://blog.csdn.net/pengdandezhi/article/details/67082171
中做了分析
MCS
MSC與CLH最大的不同並不是連結串列是顯示還是隱式,而是執行緒自旋的規則不同:CLH是在前趨結點的locked域上自旋等待,而MSC是在自己的
結點的locked域上自旋等待。正因為如此,它解決了CLH在NUMA系統架構中獲取locked域狀態記憶體過遠的問題。

相關推薦

JAVA執行——CLHMCS

自旋鎖 學習瞭解自旋鎖之前先回顧一下互斥鎖 互斥鎖 執行緒在獲取互斥鎖的時候,如果發現鎖已經被其它執行緒佔有,那麼執行緒就會驚醒休眠,然後在適當的時機(比如喚醒)在獲取鎖。 自旋鎖 那麼自旋鎖

linux執行

基本概念: 何謂自旋鎖?它是為實現保護共享資源而提出一種鎖機制。其實,自旋鎖與互斥鎖比較類似,它們都是為了解決對某項資源的互斥使用。無論是互斥鎖,還是自旋鎖,在任何時刻,最多隻能有一個保持者,也就說,在任何時刻最多隻能有一個執行單元獲得鎖。但是兩者在排程機制上略有不同。對

java執行機制二

網上看到一個題目,題目是這樣:Java多執行緒,啟動四個執行緒,兩個執行加一,另外兩個執行減一。 針對該問題寫了一個程式,測試通過,如下: class Sync { static int count = 0; public void add() {

java執行機制一

網上看了一篇關於java synchronized關鍵字使用的很好的文章,現將其簡要總結一下,加深理解。 先總結兩個規則: synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。 多個執行緒

java執行Lock--顯式

Lock與Synchronized簡介 Synchornized相信大家用的已經比較熟悉了,這裡我就不介紹它的用法了 Synchronized被稱為同步鎖或者是隱式鎖,隱式鎖與顯式鎖區別在於,隱式鎖的獲取和釋放都需要出現在一個塊結構中,而且是有順序的,獲取鎖的順序和釋放鎖的順序必須相反,就是說,

java執行(二)

一,鎖 在物件的建立時java會為每個object物件分配一個monitor( 監視器或者監視鎖),當某個物件的同步方法(synchronized methods )被多個執行緒呼叫時,該物件的monitor將負責處理這些訪問的併發獨佔要求。 當一個執行緒呼叫一個物件的同步方法時(sy

Java執行優化策略

轉載 http://www.cnblogs.com/ygj0930/p/6561264.html 編碼過程中可採取的鎖優化的思路有以下幾種: 1:減少鎖持有時間 例如:對一個方法加鎖,不如對方法中需要同步的幾行程式碼加鎖; 2:減小鎖粒度 例如:

java執行的分類

轉載:https://blog.csdn.net/nalanmingdian/article/details/77800355 上一篇既然提到了鎖,這一篇來詳細介紹JAVA中的鎖,也為之後JUC下的鎖做一個鋪墊  其實如果按照名稱來說,鎖大概有以下名詞: 自旋鎖 ,自旋鎖的其

java執行同步(Lock)

      從Java5開始,提供了Lock, Lock提供了比synchronized方法和synchronized程式碼塊更廣泛的鎖定操作,Lock可以實現更靈活的結構,並且支援多個相關的Condition物件(物件監視器)。       Lock是控制多個執行緒對共享

Java執行生產者消費者問題:使用重入條件變數優雅地解決生產者消費者問題

        Java5中新增了大量執行緒同步的功能,比如顯式Lock,讀寫鎖ReadWriteLock,條件變數Condition等,雖然這些功能使用之前的synchronized同步關鍵字都可能實現,但自己使用同步關鍵字不僅管理混亂,而且容易出錯。 如下是使用顯式Lo

JAVA執行Synchronized關鍵字--物件的特點

一,介紹 本文介紹JAVA多執行緒中的synchronized關鍵字作為物件鎖的一些知識點。 所謂物件鎖,就是就是synchronized 給某個物件 加鎖。關於 物件鎖 可參考:這篇文章 二,分析 synchronized可以修飾例項方法,如下形式: 1 public class My

java執行

在java多執行緒裡,在同步中巢狀多個同步會造成死鎖執行緒。死鎖後的程式依然在執行,多個執行緒直接互相想要對方的鎖,而自己的鎖又沒有釋放。然後就造成了死鎖現象。大家都知道synchronized是會自

Java執行的出現和解決方法

什麼是死鎖?死鎖是這樣一種情形:多個執行緒同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放.由於執行緒被無限期地阻塞,因此程式不能正常執行.形象的說就是:一個寶藏需要兩把鑰匙來開啟,同時間正好來了兩個人,他們一人一把鑰匙,但是雙方都再等著對方能交出鑰匙來開啟寶藏,誰都沒

java執行建立執行與死

執行緒建立篇    java中的執行緒建立有多種方式,筆者(ymh)這裡分別根據執行緒執行完畢後是否有返回值討論執行緒建立的四種方式。 1、通過繼承Thread類重寫run方法(無返回值) 示例程式碼:

java執行的例子

在java多執行緒編寫程式中特別害怕的一種情況就是死鎖,他會讓程式死在哪裡不在繼續執行下面就來看一個死鎖的例子: /** * 死鎖的例子 */ public class SiSuoTest

Java執行join()方法

概要 本章,會對Thread中join()方法進行介紹。涉及到的內容包括: 1. join()介紹 2. join()原始碼分析(基於JDK1.7.0_40) 3. join()示例 來源:http://www.cnblogs.com/skywang12345/p/34792

白話理解java執行join()方法

join字面意思是加入,我理解為插隊. 舉例:媽媽在炒菜,發現沒喲醬油了,讓兒子去打醬油,兒子打完醬油,媽媽炒完菜,全家一起吃 package cn.yh.thread01; /** * * 打醬油的例子 */ public class Demo03 { public stat

細說Java 執行記憶體可見性

前言: 討論學習Java中的記憶體可見性、Java記憶體模型、指令重排序、as-if-serial語義等多執行緒中偏向底層的一些知識,以及synchronized和volatile實現記憶體可見性的原理和方法。 1、可見性介紹 可見性:一個執行緒對共用變數值的修改,能夠及時地被其他執行緒

java執行 執行協作

也是網上看的一道題目:關於假如有Thread1、Thread2、Thread3、Thread4四條執行緒分別統計C、D、E、F四個盤的大小,所有執行緒都統計完畢交給Thread5執行緒去做彙總,應當如何實現? 蒐集整理了網上朋友提供的方法,主要有: 1. 多執行緒都是Thread或

java執行Phaser

java多執行緒技術提供了Phaser工具類,Phaser表示“階段器”,用來解決控制多個執行緒分階段共同完成任務的情景問題。其作用相比CountDownLatch和CyclicBarrier更加靈活,例如有這樣的一個題目:5個學生一起參加考試,一共有三道題,要求所有學生到齊才能開始考試,全部同學都