ReentrantLock类详解

简述

  ReentrantLock是juc包下的一个类,它是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活、更强大,增加了轮询、超时、中断等高级功能。

  ReenreantLock可以中断——a线程用着锁,b线程能中断,设置超时时间——在entrylist等待锁的线程在规定时间内获取不到锁就会放弃锁的获取,可以设置为公平锁——让线程都排队等先到先得,支持多个条件变量——可以理解为有多个waitset。

基本语法

  reentrantLock的锁需要新建一个对象来使用

// 获取锁
reentrantLock.lock();
try {
    // 临界区
} finally {
    // 释放锁
    reentrantLock.unlock();
}

可重入

  reentrantLock和synchronized一样,也是可重入的锁。可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住。

可打断

  使用reentrantLock可以在等锁的时候被打断,想以可以被打断的方式获取断锁用lockInterruptibly方法。其他线程可以使用该线程的interrupt方法打断该线程

锁超时

  tryLock方法代表尝试获取锁,返回boolean值,代表是否成功获取了锁。

  它还可以加一个时间参数,获取不到锁时,等待该时间,时间到则返回false

  同时需要注意的是这种方式获取锁也是可以被打断的

公平锁

  reentrantLock默认是不公平的,可以在构造方法传一个true设置reentrantLock锁为公平锁

  公平锁是用来解决饥饿问题的,线程在尝试获取锁的时候是先到先得的机制

条件变量

  reentrantLock有多个waitset,线程等待时可以选择一个进行等待,唤醒等待线程时可以选择一个waitset唤醒。

  可以用newCondition创建条件变量类,等同于创建一个waitset  

  可以调用Condition类的await进入等待队列,使用signal方法唤醒该Condition上等待的线程

  需要注意await 前需要获得锁,await 执行后,会释放锁,进入 conditionObject 等待,await 的线程被唤醒(或打断、或超时)取重新竞争 lock 锁,竞争 lock 锁成功后,从 await 后继续执行

 

posted @ 2021-08-09 07:48  艾尔夏尔-Layton  阅读(289)  评论(0编辑  收藏  举报