1. 程式人生 > >java多執行緒中顯式鎖的輪詢檢測策略

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方式

cbf1500bca32d30ada11226bb6cd3390532110fa

ReentrantLock方式

d6ce85b9173bd0c899d6043cb8a606547b117825

本案例中在lock 和unlock 中間的程式碼塊與synchronized 包裹的程式碼塊是等效的。可以保證在執行unlock之前該執行緒不會讓出資源給其它執行緒執行。

實現輪詢鎖

需求:小明和小紅去借書,但是書只有一本,假如小明借到了,看完這本書需要5秒,

在小明讀書的時間內,小紅還會多次去借書,直到小明歸還小紅才能借到。

分析:

1、小明和小紅去借書,但是書只有一本 ,從這裡可以分析出需要兩個執行緒;

2、假如小明借到了,看完這本書需要5秒,借到書可以視為獲取到鎖;

3、在小明讀書的時間內,小紅還會多次去借書,可以視為小紅未獲得鎖,所以需要多次嘗試去獲得鎖;

4、直到小明歸還小紅才能借到,可以視為小明的執行緒釋放鎖,小紅獲得鎖。

efd0321ae9a1ab49a8ca41c3b060f6b4bd704ab2

總結

不論使用synchronized 還是使用顯示鎖lock都可以解決程式碼塊同步的問題。synchronized 使用更方便,獲得鎖和釋放鎖不需要手動處理,但控制粒度不夠細緻。lock顯式鎖需要使用lock()手動加鎖,unlock()手動釋放鎖,使用起來相對複雜,但可以實現更精細的鎖控制。

使用trylock結合輪詢可以實現檢測鎖是否空閒的效果。


原文釋出時間為:2018-11-13

本文來自雲棲社群合作伙伴“Java程式設計師聯盟”,瞭解相關資訊可以關注“Java程式設計師聯盟”。