ReentrantLock 特点
相对于 synchronized 锁,它具备如下特点:
- 可中断
- 可设置超时时间
- 可设置为公平锁
- 支持多个条件变量
和 synchronized 一样都支持可重入
可重入锁:可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
不可重入锁:不可重入就是说某个线程已经获得某个锁,可以再次获取锁而会被自己锁挡住,出现死锁。
基本语法
lock 方法
reentrantLock.lock(); 是不可打断的锁;
package top.simba1949;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Anthony
* @date 2020/10/26 16:48
*/
public class Application {
ReentrantLock reentrantLock = new ReentrantLock();
public void lockMethod(){
// 获取锁
reentrantLock.lock();
try{
// 需要加锁的代码块
}finally {
// 释放锁
reentrantLock.unlock();
}
}
}
可打断的锁
package top.simba1949;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Anthony
* @date 2020/10/24 10:01
*/
public class Application {
static ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
// 设置可打断的锁
// 如果没有竞争,此方法会获取 reentrantLock 锁
// 如果有竞争会进入阻塞队列中,可以被其他线程用 interrupt 方法打断
reentrantLock.lockInterruptibly();
try{
// 需要加锁的代码块
}finally {
// 释放锁
reentrantLock.unlock();
}
}
}
防止锁超时
reentrantLock.tryLock() 尝试获取,可以避免死锁;
package top.simba1949;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Anthony
* @date 2020/10/24 10:01
*/
public class Application {
static ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) {
// 尝试获取锁,true 为获取成功,false 表示获取不到锁
boolean bl = reentrantLock.tryLock();
if (!bl){
// 获取不到锁的处理逻辑
return;
}
try{
//需要加锁的代码块
}finally {
// 释放锁
reentrantLock.unlock();
}
}
}
ReentrantLock公平锁
ReentrantLock 默认是不公平锁
公平锁:按照先入先得
公平锁会降低线程的并发度;
// 构造方法传入 true ,设置为公平锁
ReentrantLock reentrantLock = new ReentrantLock(true);
条件变量
package top.simba1949;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Anthony
* @date 2020/10/24 10:01
*/
public class Application {
static ReentrantLock reentrantLock = new ReentrantLock(true);
public static void main(String[] args) throws InterruptedException {
// 创建一个条件变量(休息室)
Condition condition = reentrantLock.newCondition();
reentrantLock.lock();
try{
// 进入休息室休息,await前需要获取锁,
// await执行后释放锁,进入 ConditionObject 等待
// await被线程唤醒(打断、超时)去重新竞争 lock 锁,竞争成功后,会从await后执行
condition.await();
// 唤醒一个等待的线程
condition.signal();
}finally {
// 释放锁
reentrantLock.unlock();
}
}
}