java多執行緒中顯式鎖的輪詢檢測策略
顯式鎖簡介
java5.0之前,在協調對共享物件的訪問時可以使用的機制只有synchronized和volatile,java5.0增加了一種新的機制:ReentrantLock。
鎖像synchronized同步塊一樣,是一種執行緒同步機制,與synchronized不同的是ReentrantLock提供了一種無條件的、可輪詢的、定時的以及可以中斷的鎖獲取操作,並且所有的加鎖和解鎖的方法都是顯式的,所以也叫顯式鎖。
synchronized的實現中包含了鎖機制,但是鎖的獲取和釋放不能人為的進行控制,所以當我們要定時獲取鎖,檢測鎖是否被佔用時就應當使用顯式鎖。
顯式鎖涉及的類和介面
ReentrantLock實現了Lock介面,位於Java的J.U.C包中,包含了一下幾個主要方法:
1、void lock(),獲取鎖;
2、void unlock(),釋放鎖;
3、boolean trylock(),僅在呼叫時鎖為空閒狀態才獲取該鎖;
4、boolean tryLock(long time, TimeUnit unit),如果鎖在給定的等待時間內空閒,並且當前執行緒未被中斷,則獲取鎖。
顯式鎖的簡單使用
下面我們就分別使用synchronized和lock實現小紅借書的需求。
需求:小明和小紅去借書,每人借10本。一個人借完之後才允許另外一個人借。
分析:
1、小明和小紅相當於 2個執行緒;
2、借10本書視為一個操作即迴圈10次;
3、一個人借完之後才允許另外一個人借。
要實現必須保證借書的10次操作中間不能發生執行緒的切換,因此可以使用 synchronized 同步塊或顯示鎖 ReentrantLock 來保證。
synchronized方式
ReentrantLock方式
本案例中在lock 和unlock 中間的程式碼塊與synchronized 包裹的程式碼塊是等效的。可以保證在執行unlock之前該執行緒不會讓出資源給其它執行緒執行。
實現輪詢鎖
需求:小明和小紅去借書,但是書只有一本,假如小明借到了,看完這本書需要5秒,
在小明讀書的時間內,小紅還會多次去借書,直到小明歸還小紅才能借到。
分析:
1、小明和小紅去借書,但是書只有一本 ,從這裡可以分析出需要兩個執行緒;
2、假如小明借到了,看完這本書需要5秒,借到書可以視為獲取到鎖;
3、在小明讀書的時間內,小紅還會多次去借書,可以視為小紅未獲得鎖,所以需要多次嘗試去獲得鎖;
4、直到小明歸還小紅才能借到,可以視為小明的執行緒釋放鎖,小紅獲得鎖。
總結
不論使用synchronized 還是使用顯示鎖lock都可以解決程式碼塊同步的問題。synchronized 使用更方便,獲得鎖和釋放鎖不需要手動處理,但控制粒度不夠細緻。lock顯式鎖需要使用lock()手動加鎖,unlock()手動釋放鎖,使用起來相對複雜,但可以實現更精細的鎖控制。
使用trylock結合輪詢可以實現檢測鎖是否空閒的效果。
原文釋出時間為:2018-11-13
本文來自雲棲社群合作伙伴“Java程式設計師聯盟”,瞭解相關資訊可以關注“Java程式設計師聯盟”。