1. 程式人生 > >Java中的鎖池和等待池

Java中的鎖池和等待池

Java平臺中,因為有內建鎖的機制,每個物件都可以承擔鎖的功能。Java虛擬機器會為每個物件維護兩個“佇列”(姑且稱之為“佇列”,儘管它不一定符合資料結構上佇列的“先進先出”原則):一個叫Entry Set(入口集),另外一個叫Wait Set(等待集)。對於任意的物件objectX,objectX的Entry Set用於儲存等待獲取objectX這個鎖的所有執行緒,也就是傳說中的鎖池,objectX的Wait Set用於儲存執行了objectX.wait()/wait(long)的執行緒,也就是等待池。

先來一張執行緒的狀態圖:

設objectX是任意一個物件,假設有執行緒A、B、C同時申請objectX這個物件鎖,那麼由於任意一個時刻只有一個執行緒能夠獲得(佔用/持有)這個鎖,因此除了勝出(即獲得了鎖)的執行緒(這裡假設是B)外,其他執行緒(這裡就是A和C)都會被暫停(執行緒的生命週期狀態會被調整為BLOCKED)。這些因申請鎖而落選的執行緒就會被存入objectX對應的鎖池之中。當objectX被其持有執行緒(這裡就是B)釋放時,鎖池中的一個任意(注意是“任意”,而不一定是鎖池中等待時間最長或者最短的

)執行緒會被喚醒(即執行緒的生命週期狀態變更為RUNNABLE)。這個被喚醒的執行緒會與其他活躍執行緒(即不處於鎖池之中,且執行緒的生命週期狀態為RUNNABLE的執行緒)再次搶佔objectX。這時,被喚醒的執行緒如果成功申請到objectX,那麼該執行緒就從鎖池中移除。否則,被喚醒的執行緒仍然會停留在鎖池中,並再次被暫停,以等待下次申請鎖的機會。

如果有個執行緒執行了objectX.wait(),那麼該執行緒就會被暫停(執行緒的生命週期狀態會被調整為Waiting),並且會釋放掉objectX鎖,然後被存入objectX的等待池之中。此時,該執行緒就被稱為objectX的等待執行緒。當其他執行緒執行了objectX.notify()/notifyAll()時,等待池中的一個(或者多個,取決於被呼叫的是notify還是notifyAll方法)任意(注意是“任意”,而不一定是等待池中等待時間最長或者最短的)

等待執行緒會被喚醒,這些被喚醒的執行緒會被放到鎖池中,會與鎖池中已經存在的執行緒以及其他(可能的)活躍執行緒共同參與搶奪objectX。至於程式碼中到底是使用notify還是notifyAll方法,這個要根據實際情況來分析。

ps:等待池中的執行緒被notify()或者notifyAll()方法喚醒進入到鎖池,最後競爭到了鎖並且進入了Runnable狀態的話,會從wait現場恢復,執行wait()方法之後的程式碼。

以上是個人理解,如果有誤,請在評論區中指正!

相關推薦

多執行緒---java等待的概念

鎖池和等待池 在java中,每個物件都有兩個池,鎖(monitor)池和等待池 鎖池:假設執行緒A已經擁有了某個物件(注意:不是類)的鎖,而其它的執行緒想要呼叫這個物件的某個synchronized方法(或者synchronized塊),由於這些執行緒在進入物件的synchronize

Java等待

Java平臺中,因為有內建鎖的機制,每個物件都可以承擔鎖的功能。Java虛擬機器會為每個物件維護兩個“佇列”(姑且稱之為“佇列”,儘管它不一定符合資料結構上佇列的“先進先出”原則):一個叫Entry Set(入口集),另外一個叫Wait Set(等待集)。對於任意的物件obj

Java常用面試題15 synchronized方法的妙用 等待的區別

問: 當一個執行緒進入一個物件的synchronized方法A之後,其它執行緒是否可進入此物件的synchronized方法B?  答: 不能。其它執行緒只能訪問該物件的非同步方法,同步方法則不能進入。因為非靜態方法上的synchronized修飾符要求執行方法時要獲得

leep()wait()方法與物件等待

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u014561933/article/details/58639411 一道Java的題目: 關於sleep()和wait(),以下描述錯誤的一項是: - A sleep是

初識Java的四大執行緒ThreadPoolExecutor的使用(歡迎指正)

初識Java中的四大執行緒池和ThreadPoolExecutor的使用(轉載+自身心得) 為什麼用執行緒池? 1.建立/銷燬執行緒伴隨著系統開銷,過於頻繁的建立/銷燬執行緒,會很大程度上影響處-理效率; 2.執行緒併發數量過多,搶佔系統資源從而導致阻塞; 3.對執行緒進行一些簡單的

java常見的執行緒(不看後悔,一看必懂)

Executor介面表示執行緒池,它的execute(Runnable task)方法用來執行Runnable型別的任務,ExecutorService是Executor的子介面,聲明瞭管理執行緒池的一些方法 Java.util.concurrent.Executors類包含了一些靜態

JAVAInteger及其資料緩衝

在寫本節內容前,首先說明JDK1.5後增加的一個新特性:自動裝箱和拆箱 Integer i5=127; i5=i5+100; System.out.println(i5); 輸出結果為227 對於

Java堆、棧常量

轉自:http://www.iteye.com/topic/634530 暫存器:最快的儲存區, 由編譯器根據需求進行分配,我們在程式中無法控制; 棧:存放基本型別的變數資料和物件的引用,但物件本身不存放在棧中,而是存放在堆(new 出來的物件)或者常量池中(字串常量物件存

Java堆、棧常量以及相關String的講解

一:在JAVA中,有六個不同的地方可以儲存資料:   1. 暫存器(register)。 這是最快的儲存區,因為它位於不同於其他儲存區的地方——處理器內部。但是暫存器的數量極其有限,所以暫存器由編譯器根據需求進行分配。你不能直接控制,也不能在程式中感覺到暫存器存在的任何

UA代理在scrapy的應用

一.下載中介軟體 下載中介軟體(Downloader Middlewares) 位於scrapy引擎和下載器之間的一層元件。 - 作用: (1)引擎將請求傳遞給下載器過程中, 下載中介軟體可以對請求進行一系列處理。比如設定請求的 User-Agent,設定代理等 (2)在下載器完成將Response傳

JavaJDBC的資料庫連線

資料庫連線池 池引數(所有池引數都有預設值): 初始大小:10個 最小空閒連線數:3個 增量:一次建立的最小單位(5個) 最大空閒連線數:12個 最大連線數:20個 最大的等待時間:1000毫秒 四

Java的BoneCP資料庫連線

最近在學習公司的框架,涉及到連線資料庫部分的技術時,發現用的是BoneCP,上網查閱了相關資料與例子,個人覺得下面這例子比較容易懂,有收藏的價值存在,故將其放在自己的部落格裡,供學習時參考:  BoneCP is a fast, free, open-source, Jav

Java的幾種常量

參考https://www.zhihu.com/question/55994121 1.執行時常量池:方法區的一部分,存放編譯器生成的各種字面量和符號引用,這部分內容將在類載入後進入方法區的執行時常量池。一般來說,除了儲存Class檔案中描述的符號引用外,還會把翻譯出來的直

Java五種執行緒的介紹

如果不希望任務在佇列中等待而是希望將任務直接移交給工作執行緒,可使用SynchronousQueue作為等待佇列。SynchronousQueue不是一個真正的佇列,而是一種執行緒之間移交的機制。要將一個元素放入SynchronousQueue中,必須有另一個執行緒正在等待接收這個元素。只有在使用無界執行

java四種執行緒的區別

本文按: 一. 執行緒池的使用 二. 幾種執行緒池的區別 三. 如何合理配置執行緒池 一.執行緒池的使用 在Java中,通常使用Executors 獲取執行緒池。常用的執行緒池有以下幾種: (1)CachedThreadPool (2)FixedThreadPo

10 UA代理在Scrapy的應用

 下載中介軟體簡介   在Scrapy中,引擎和下載器之間有一個元件,叫下載中介軟體(Downloader Middlewares)。因它是介於Scrapy的request/response處理的鉤子,所以有2方面作用: (1)引擎將請求傳遞給下載器過程中,下載中介軟體可以對Requests進行一系

詳解執行緒的作用及Java如何使用執行緒

![](https://img2020.cnblogs.com/other/1815316/202101/1815316-20210114083352253-122112091.png) 服務端應用程式(如資料庫和 Web 伺服器)需要處理來自客戶端的高併發、耗時較短的請求任務,所以頻繁的建立處理這些請求的所

Java 的堆

同時 存在 堆棧 color 特殊性 垃圾回收器 速度 自動釋放 靈活  Java把內存劃分成兩種:一種是棧內存,一種是堆內存。 在Java中所有對象的存儲空間都是在堆中分配的,但是這個對象的引用卻是在堆棧中分配,也就是說在建立一個對象時從兩個地方都分配內存,在堆中

Java接口抽象類的比較

系列 分享 space 日誌信息 pub 指向 相關 最好的 就會 Java中接口和抽象類的比較-2013年5月寫的讀書筆記摘要 1. 概述 接口(Interface)和抽象類(abstract class)是 Java 語言中支持抽象類的兩種機制,是

JAVA堆棧內存分配詳解(摘抄)

如果 public china weight 所有 有道 動態 面試題 class 在Java中,有六個不同的地方可以存儲數據: 1.寄存器:最快的存儲區, 由編譯器根據需求進行分配,我們在程序中無法控制. 2. 棧:存放基本類型的變量數據和對象的引用,但對象本身不存放在棧