ReentrantLock 特点

相对于 synchronized 锁,它具备如下特点:

  • 可中断
  • 可设置超时时间
  • 可设置为公平锁
  • 支持多个条件变量

和 synchronized 一样都支持可重入

可重入锁:可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
不可重入锁:不可重入就是说某个线程已经获得某个锁,可以再次获取锁而会被自己锁挡住,出现死锁。

基本语法

lock 方法

reentrantLock.lock(); 是不可打断的锁;

  1. package top.simba1949;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. /**
  4. * @author Anthony
  5. * @date 2020/10/26 16:48
  6. */
  7. public class Application {
  8. ReentrantLock reentrantLock = new ReentrantLock();
  9. public void lockMethod(){
  10. // 获取锁
  11. reentrantLock.lock();
  12. try{
  13. // 需要加锁的代码块
  14. }finally {
  15. // 释放锁
  16. reentrantLock.unlock();
  17. }
  18. }
  19. }

可打断的锁

  1. package top.simba1949;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. /**
  4. * @author Anthony
  5. * @date 2020/10/24 10:01
  6. */
  7. public class Application {
  8. static ReentrantLock reentrantLock = new ReentrantLock();
  9. public static void main(String[] args) throws InterruptedException {
  10. // 设置可打断的锁
  11. // 如果没有竞争,此方法会获取 reentrantLock 锁
  12. // 如果有竞争会进入阻塞队列中,可以被其他线程用 interrupt 方法打断
  13. reentrantLock.lockInterruptibly();
  14. try{
  15. // 需要加锁的代码块
  16. }finally {
  17. // 释放锁
  18. reentrantLock.unlock();
  19. }
  20. }
  21. }

防止锁超时

reentrantLock.tryLock() 尝试获取,可以避免死锁;

  1. package top.simba1949;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. /**
  4. * @author Anthony
  5. * @date 2020/10/24 10:01
  6. */
  7. public class Application {
  8. static ReentrantLock reentrantLock = new ReentrantLock();
  9. public static void main(String[] args) {
  10. // 尝试获取锁,true 为获取成功,false 表示获取不到锁
  11. boolean bl = reentrantLock.tryLock();
  12. if (!bl){
  13. // 获取不到锁的处理逻辑
  14. return;
  15. }
  16. try{
  17. //需要加锁的代码块
  18. }finally {
  19. // 释放锁
  20. reentrantLock.unlock();
  21. }
  22. }
  23. }

ReentrantLock公平锁

ReentrantLock 默认是不公平锁
公平锁:按照先入先得
公平锁会降低线程的并发度;

  1. // 构造方法传入 true ,设置为公平锁
  2. ReentrantLock reentrantLock = new ReentrantLock(true);

条件变量

  1. package top.simba1949;
  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. /**
  5. * @author Anthony
  6. * @date 2020/10/24 10:01
  7. */
  8. public class Application {
  9. static ReentrantLock reentrantLock = new ReentrantLock(true);
  10. public static void main(String[] args) throws InterruptedException {
  11. // 创建一个条件变量(休息室)
  12. Condition condition = reentrantLock.newCondition();
  13. reentrantLock.lock();
  14. try{
  15. // 进入休息室休息,await前需要获取锁,
  16. // await执行后释放锁,进入 ConditionObject 等待
  17. // await被线程唤醒(打断、超时)去重新竞争 lock 锁,竞争成功后,会从await后执行
  18. condition.await();
  19. // 唤醒一个等待的线程
  20. condition.signal();
  21. }finally {
  22. // 释放锁
  23. reentrantLock.unlock();
  24. }
  25. }
  26. }