重進(jìn)入是指任意線程在獲取鎖以后,能夠再次獲取該鎖而不會(huì)被鎖所阻塞
大白話就是說(shuō)一個(gè)加鎖的方法里面調(diào)用同一對(duì)象中另外一個(gè)加鎖的方法可以直接獲取鎖,不會(huì)阻塞
閱讀完后可以大概了解一下ReentrantLock是個(gè)什么東東,然后最好自己去擼下源碼,看下原理。
構(gòu)造
//創(chuàng)建一個(gè)非公平獲取鎖的ReentrantLock實(shí)例
ReentrantLock()
//使用給定的公平性策略創(chuàng)建ReentrantLock實(shí)例
//true : 公平獲取鎖
//false: 非公平獲取鎖 (默認(rèn))
ReentrantLock(boolean fair)
ReentrantLock 方法
| 類型 | 方法 | 描述 |
|---|---|---|
| int | getHoldCount() | 當(dāng)前線程對(duì)此鎖的持有數(shù),如果當(dāng)前線程不持有此鎖,則為零 |
| protected Thread | getOwner() | 返回當(dāng)前擁有此鎖的線程,如果不擁有該鎖,則返回null |
| protected Collection<Thread> | getQueuedThreads() | 返回一個(gè)包含可能正在等待獲取此鎖的線程的集合 |
| int | getQueueLength() | 返回等待獲取此鎖的線程數(shù) |
| protected Collection<Thread> | getWaitingThreads(Condition condition) | 返回一個(gè)集合,該集合包含那些可能正在等待與此鎖關(guān)聯(lián)的給定條件的線程 |
| int | getWaitQueueLength(Condition condition) | 返回等待與此鎖關(guān)聯(lián)的給定條件的線程數(shù) |
| boolean | hasQueuedThread(Thread thread) | 查詢給定線程是否正在等待獲取此鎖 |
| boolean | hasQueuedThreads() | 查詢是否有任何線程正在等待獲取此鎖 |
| boolean | hasWaiters(Condition condition) | 查詢是否有線程正在等待與此鎖關(guān)聯(lián)的給定條件 |
| boolean | isFair() | 獲取公平性策略,公平鎖返回ture,反之返回false |
| boolean | isHeldByCurrentThread() | 查詢此鎖是否由當(dāng)前線程持有 |
| boolean | isLocked() | 查詢是否有線程持有鎖 |
| void | lockInterruptibly() | 獲取鎖,除非當(dāng)前線程被中斷 |
| Condition | newCondition() | 返回用于此鎖實(shí)例的條件實(shí)例 |
| String | toString() | 返回標(biāo)識(shí)此鎖的字符串及其鎖定狀態(tài) |
| boolean | tryLock() | 僅在調(diào)用時(shí)其他線程未持有該鎖時(shí)才獲取該鎖 |
| boolean | tryLock(long timeout, TimeUnit unit) | 如果在給定的等待時(shí)間內(nèi)沒有被另一個(gè)線程持有,并且當(dāng)前線程沒有被中斷,則獲取該鎖 |
| void | unlock() | 釋放鎖 |
例子
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.locks.ReentrantLock;
/**
* Description: thread
*
* @author songyu
*/
public class ReentrantLockTest {
static DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
static ReentrantLock lock = new ReentrantLock();
public static void test(int i) {
//獲取鎖
lock.lock();
try {
LocalDateTime now = LocalDateTime.now();
System.out.println( now.format(fmTime) + " 第" + i + "個(gè)線程獲取到鎖,等待5秒,釋放鎖");
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放鎖
lock.unlock();
}
}
public static void main(String[] args) {
//連續(xù)調(diào)用五次test()方法
for (int i = 1; i <= 5; i++ ) {
test(i);
}
}
}
執(zhí)行結(jié)果
2020-07-10 17:24:50 第1個(gè)線程獲取到鎖,等待5秒,釋放鎖
2020-07-10 17:24:55 第2個(gè)線程獲取到鎖,等待5秒,釋放鎖
2020-07-10 17:25:00 第3個(gè)線程獲取到鎖,等待5秒,釋放鎖
2020-07-10 17:25:05 第4個(gè)線程獲取到鎖,等待5秒,釋放鎖
2020-07-10 17:25:10 第5個(gè)線程獲取到鎖,等待5秒,釋放鎖
例子 - 重進(jìn)入
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.locks.ReentrantLock;
/**
* Description: thread
*
* @author songyu
*/
public class ReentrantLockTest1 {
static DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
static ReentrantLock lock = new ReentrantLock(){};
public static void test(int i) {
System.out.println("");
lock.lock();
try {
LocalDateTime now = LocalDateTime.now();
System.out.println( now.format(fmTime) + " 第" + i + "次調(diào)用進(jìn)入方法,等待5秒,釋放鎖");
//調(diào)用另一個(gè)需要獲取鎖的方法
test2(i);
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void test2(int i) {
lock.lock();
try {
LocalDateTime now2 = LocalDateTime.now();
//獲取當(dāng)前線程對(duì)鎖的持有數(shù)
int holdCount = lock.getHoldCount();
System.out.println( now2.format(fmTime) + " 第" + i + "次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
test(i);
}
}
}
執(zhí)行結(jié)果
2020-07-10 18:14:04 第0次調(diào)用進(jìn)入方法,等待5秒,釋放鎖
2020-07-10 18:14:04 第0次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞
2020-07-10 18:14:09 第1次調(diào)用進(jìn)入方法,等待5秒,釋放鎖
2020-07-10 18:14:09 第1次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞
2020-07-10 18:14:14 第2次調(diào)用進(jìn)入方法,等待5秒,釋放鎖
2020-07-10 18:14:14 第2次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞
2020-07-10 18:14:19 第3次調(diào)用進(jìn)入方法,等待5秒,釋放鎖
2020-07-10 18:14:19 第3次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞
2020-07-10 18:14:24 第4次調(diào)用進(jìn)入方法,等待5秒,釋放鎖
2020-07-10 18:14:24 第4次調(diào)用 - - 調(diào)用第二個(gè)需要獲取鎖的方法 成功再次獲取鎖,未阻塞
線程重復(fù)獲取了N次鎖,只有當(dāng)線程釋放了N次鎖以后,其它的線程才能獲取鎖。