concurrent包之reentrantlock

接觸過併發的同學對concurrent包肯定並不陌生,reentrantlock就是java.util.concurrent.locks包下面的東西,這裏面還有我們熟悉的其他可提供線程安全的類,如讀寫鎖,以及aqs這個最經典的類,今天我們主要簡單分享下reentrantlock,其他的會在之後進行分享

首先reentrantlock是什麼,毫無疑問是一個鎖,那他同我們曾經使用過的synchronized的有什麼區別呢,就我比較對它比較膚淺的認識來說,它比synchronized更爲靈活,首先我們在實例化reentrantlock的時候傳入的boolean值是指是否使用公平鎖,這裏就公平鎖和非公平鎖廢話一下,我們看過aqs源碼的同學都知道里面有一hasQueuedPredecessors方法來判斷等待隊列裏是否有線程,如果發現有線程在等待則不盡興搶佔,這個就是公平鎖,而不判斷隊列是否有線程直接進行搶佔,這就是非公平鎖,reentrantlock裏面的sync繼承了aqs類,所以也就有着這麼兩種鎖,如果構造不傳參數默認爲非公平鎖,這個我們都可以通過源碼看到

除了這一點,reentrantlock還有一個tryLock(int,util)這麼個方法,這個方法的作用就是判斷線程等待時間是否超過了int這個值,而int的單位由util決定,我們看下面一個小demo

public class ReentrantLockDemo {
	public static void main(String[] args) {
		ReentrantLock reentrantLock = new ReentrantLock(true);
		
		Runnable runnable = new Runnable() {
			Thread thread  = Thread.currentThread();
			@Override
			public void run() {
				try {
					if(!reentrantLock.tryLock(3, TimeUnit.SECONDS)){
						System.out.println("thread:"+thread.currentThread().getName()+" 不等了");
						return;
					}
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				try{
					System.out.println("thread:"+thread.currentThread().getName()+" start");
					Thread.sleep(2000);
					System.out.println("thread:"+thread.currentThread().getName()+" end");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}finally{
					reentrantLock.unlock();
				}
			}
		};
		
		for (int i = 0; i < 10; i++) {
			Thread thread = new Thread(runnable);
			thread.start();
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		
	}
}
打印結果爲

thread:Thread-0 start

thread:Thread-0 end

thread:Thread-1 start

thread:Thread-2 不等了

thread:Thread-3 不等了

thread:Thread-4 不等了

thread:Thread-5 不等了

thread:Thread-6 不等了

thread:Thread-7 不等了

thread:Thread-8 不等了

thread:Thread-9 不等了

thread:Thread-1 end


這裏理解挺容易的,因爲每個線程我們都讓他睡眠2秒,然而其他線程最大的耐心是等待3秒,因此在第二個線程搶佔到資源以後繼續等待2秒,其他線程就已經迫不及待等不下去了,執行了return操作

這個應用還是較爲廣泛的,如果一味等下去如果當前線程出問題了鎖釋放不掉則會造成線程阻塞

由於sync繼承自aqs類,所以我們不難發現它其實有很多方法來自父類例如release,setExclusiveOwnerThread等,如果瞭解aqs類的同學肯定都很熟悉這些方法,今天簡單的分享就到這裏,主要想大家引薦reentrantlock這個類以及它的一些優於synchronized的方法,如有不對請及時留言,共同進步


發佈了65 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章