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();}}}
