JAVA并發篇_公平鎖與非公平鎖

簡單的來說,如果一個線程組里,能保證每個線程都能拿到鎖,那么這個鎖就是公平鎖。相反,如果保證不了每個線程都能拿到鎖,也就是存在有線程餓死,那么這個鎖就是非公平鎖。

一、引入概念

1、公平鎖:

多個線程按照申請鎖的順序去獲得鎖,線程會直接進?隊列去排隊,永遠都是隊列的第?位才能得到鎖。

優點:所有的線程都能得到資源,不會餓死在隊列中。

缺點:吞吐量會下降很多,隊列??除了第?個線程,其他的線程都會阻塞,cpu喚醒阻塞線程的

開銷會很?。

2、?公平鎖:

多個線程去獲取鎖的時候,會直接去嘗試獲取,獲取不到,再去進?等待隊列,如果能獲取到,就直接獲取到鎖。

優點:可以減少CPU喚醒線程的開銷,整體的吞吐效率會?點,CPU也不必取喚醒所有線程,會減少喚起線程的數量。

缺點:可能導致隊列中間的線程?直獲取不到鎖或者?時間獲取不到鎖,導致餓死。

二、Java中的實現

如何能保證每個線程都能拿到鎖呢,隊列FIFO是一個完美的解決方案,也就是先進先出,java的ReenTrantLock也就是用隊列實現的公平鎖和非公平鎖。

在公平的鎖中,如果有另一個線程持有鎖或者有其他線程在等待隊列中等待這個所,那么新發出的請求的線程將被放入到隊列中。而非公平鎖上,只有當鎖被某個線程持有時,新發出請求的線程才會被放入隊列中(此時和公平鎖是一樣的)。所以,它們的差別在于非公平鎖會有更多的機會去搶占鎖。

1、公平獲取鎖

java.util.concurrent.locks.ReentrantLock$FairSync.javaprotected final boolean tryAcquire( int acquires) {final Thread current = Thread.currentThread();int c = getState();//狀態為0,說明當前沒有線程占有鎖if (c ==  0 ) {//如果當前線程是等待隊列的第一個或者等待隊列為空,則通過cas指令設置state為1,當前線程獲得鎖if (isFirst(current) &&compareAndSetState( 0 , acquires)) {setExclusiveOwnerThread(current);return true ;}}
//如果當前線程本身就持有鎖,那么疊加狀態值,持續獲得鎖else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc <  0 )throw new Error( "Maximum lock count exceeded" );setState(nextc);return true ;}//以上條件都不滿足,那么線程進入等待隊列。return false ;
}

2、非公平獲取鎖

java.util.concurrent.locks.ReentrantLock$Sync.javafinal boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//如果當前沒有線程占有鎖,當前線程直接通過cas指令占有鎖,無視等待隊列,就算自己排在隊尾也是這樣if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}

三、適用場景

更多的是直接使用非公平鎖:非公平鎖比公平鎖性能高5-10倍,因為公平鎖需要在多核情況下維護一個隊列,如果當前線程不是隊列的第一個無法獲取鎖,增加了線程切換次數。

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

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

相關文章

Java并發篇_進程線程

一個進程包括由操作系統分配的內存空間&#xff0c;包含一個或多個線程。一個線程不能獨立的存在&#xff0c;它必須是進程的一部分。一個進程一直運行&#xff0c;直到所有的非守護線程都結束運行后才能結束。 多線程能滿足程序員編寫高效率的程序來達到充分利用 CPU 的目的。…

Real提示“作為受限用戶,您無足夠的windows操作權限”的解決辦法

運行Regedit.exe&#xff0c;翻到HKEY_CLASSES_ROOT/Software&#xff0c;刪除Software&#xff1b;然后關閉注冊表&#xff0c;再運行Regedit.exe&#xff0c;翻到HKEY_CLASSES_ROOT/Software&#xff0c;點右鍵選擇“權限”&#xff0c;各個組都設置為“完全控制”和“讀取”…

Java并發篇_線程詳解

線程&#xff08;thread&#xff09; 是操作系統能夠進行運算調度的最小單位。它被包含在進程之中&#xff0c;是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流&#xff0c;一個進程中可以并發多個線程&#xff0c;每條線程并行執行不同的任務。 一、線程的…

修改MYSQL最大連接數的3種方法

MYSQL數據庫安裝完成后&#xff0c;默認最大連接數是100&#xff0c;一般流量稍微大一點的論壇或網站這個連接數是遠遠不夠的&#xff0c;增加默認MYSQL連接數的方法有兩個 方法一&#xff1a;進入MYSQL安裝目錄 打開MYSQL配置文件 my.ini 或 my.cnf查找 max_connections100 …

可擴展的編程語言——Scala

一、Scala是什么 Scala是一種多范式的編程語言&#xff0c;其設計的初衷是要集成面向對象編程和函數式編程的各種特性。Scala運行于Java平臺&#xff08;Java虛擬機&#xff09;&#xff0c;并兼容現有的Java程序。 ? Scala語言的名稱來自于"可伸展的語言"。之所以…

ubuntu7.10 apache+php+mysql配置

本篇文章 經過許多次的測試和修改已經完成了在Ubuntu7.10 下 安裝配置 ApachePHPMySQL的所有的工作. 1、在Ubuntu7.10 下安裝 Apache2PHP5MySQL sudo apt-get install apache2 libapache2-mod-php5 php5 php5-gd mysql-server php5-mysql phpmyadmin在下載來自動安裝配置的時候…

Spark-大規模數據處理計算引擎

官網&#xff1a;http://spark.apache.org 一、Spark是什么 Spark是一種快速、通用、可擴展的大數據分析引擎&#xff0c;2009年誕生于加州大學伯克利分校AMPLab&#xff0c;2010年開源&#xff0c;2013年6月成為Apache孵化項目&#xff0c;2014年2月成為Apache頂級項目。項目是…

MySQL Replace INTO的使用

REPLACE的運行與INSERT很相像。只有一點除外&#xff0c;如果表中的一個舊記錄與一個用于PRIMARY KEY或一個UNIQUE索引的新記錄具有相同的值&#xff0c;則在新記錄被插入之前&#xff0c;舊記錄被刪除。請參見13.2.4節&#xff0c;“INSERT語法”。 注意&#xff0c;除非表有…

CentOS7下Spark集群的安裝

從物理部署層面上來看&#xff0c;Spark主要分為兩種類型的節點&#xff0c;Master節點和Worker節點&#xff0c;Master節點主要運行集群管理器的中心化部分&#xff0c;所承載的作用是分配Application到Worker節點&#xff0c;維護Worker節點&#xff0c;Driver&#xff0c;Ap…

Scala中class與object區別

calss scala編譯器會字段幫我們生產一個私有字段和2個公有方法get和set scala 中沒有 static 關鍵字&#xff0c;所以 對于一個class來說&#xff0c;所有的方法和成員變量在實例被 new 出來之前都是無法訪問的 因此在class中的main方法沒什么用了 scala 的object 中所有成員…

如何編寫一個shell腳本

本文結合大量實例闡述如何編寫一個shell腳本。 為什么要進行shell編程 在Linux系統中&#xff0c;雖然有各種各樣的圖形化接口工具&#xff0c;但是sell仍然是一個非常靈活的工具。Shell不僅僅是命令的收集&#xff0c;而且是一門非常棒的編程語言。您可以通過使用shell使大量的…

Scala變量和常用數據類型

一、 聲明值和變量 Scala聲明變量有兩種方式&#xff0c;一個用val&#xff0c;一個用var。 聲明方式&#xff1a;val / var 變量名 : 變量類型 變量值 val定義的值是不可變的&#xff0c;它不是一個常量&#xff0c;是不可變量&#xff0c;或稱之為只讀變量。 val示例&am…

ubuntu7.10下的vi用的怪怪的

到網上查了一下,原來是ubuntu7.10默認安裝的是vim-tiny.可以重新安裝vim-full #dpkg -l 如果是vim-tiny #apt-get install vim-full

(轉)JVM監控工具介紹

2008年03月04日 16:57原作者&#xff1a; stone2083 原文地址&#xff1a;http://www.blogjava.net/stone2083/archive/2008/02/25/182081.htmljstatd啟動jvm監控服務。它是一個基于rmi的應用&#xff0c;向遠程機器提供本機jvm應用程序的信息。默認端口1099。實例&#xff1a;…

Scala的控制結構

一、 if else表達式 scala中沒有三目運算符&#xff0c;因為根本不需要。scala中if else表達式是有返回值的&#xff0c;如果if或者else返回的類型不一樣&#xff0c;就返回Any類型&#xff08;所有類型的公共超類型&#xff09;。 例如&#xff1a;if else返回類型一樣 scal…

【Kubernetes】控制器Statefulset

Statefulset控制器 一、概念二、Statefulset資源清單文件編寫技巧2.1、查看定義Statefulset資源需要的字段2.2、查看statefulset.spec字段如何定義2.3、查看statefulset的spec.template字段如何定義 三、Statefulset使用案例&#xff1a;部署web站點3.1、編寫一個Statefulset資…

Scala 函數

scala定義函數的標準格式為&#xff1a; def 函數名(參數名1: 參數類型1, 參數名2: 參數類型2) : 返回類型 {函數體} 函數示例1&#xff1a;返回Unit類型的函數 def shout1(content: String) : Unit {println(content) }函數示例2&#xff1a;返回Unit類型的函數&#xff0…

ubuntu7.10中的apache的一些設置

在/etc/apache2/mods-available目錄下是apache2可用的模塊.出現在這里的模塊不代表你可以用.只是表明你的apache2已經安裝了這些模塊.可用的模塊在/etc/apache2/mods-enabled這個目錄下.(從redhat系列轉過來看ubuntu,雖然感覺不習慣,但覺得ubuntu的這種分目錄的方法很不錯.) 如…

Java并發篇_Java內存模型

在并發編程中&#xff0c;我們通常會遇到以下三個問題&#xff1a;原子性問題&#xff0c;可見性問題&#xff0c;有序性問題。那么它們產生的原因和在Java中解決的辦法又是什么呢&#xff1f; 一、內存模型的相關概念 ? 計算機在執行程序時&#xff0c;每條指令都是在CPU中執…

rz的安裝

以前,在redhat系列的linux中,通過終端工具操作服務器,經常使用rz來上傳小文件.但是有些系統默認情況下不能使用此命令.今天通過ubuntu.看到這條命令.即使ubunt沒有裝這個命令,你輸入此命令時,它會提示你進行安裝. rootubuntu:~# rzThe program rz is currently not installed. …