1. 前言
本节内容主要是对 ReentrantLock 的使用进行讲解,之前对于 Lock 接口进行了讲解,ReentrantLock 是 Lock 接口的常用实现子类,占据着十分重要的地位。本节内容的知识点如下:
- ReentrantLock 基本方法的使用,即 lock 与 unlock 方法的使用,这是最基础的方法使用,为重点内容;
- ReentrantLock lockInterruptibly 与 tryLock 方法的使用,也是经常使用到的方法,为本节重点内容;
- ReentrantLock 公平锁与非公平锁的使用,也是本节的重点内容;
- ReentrantLock 其他方法的介绍与使用。
通篇来看,ReentrantLock 所有的知识点均为重点内容,是必须要掌握的内容。
2. ReentrantLock 介绍
ReentrantLock 在 Java 中也是一个基础的锁,ReentrantLock 实现 Lock 接口提供一系列的基础函数,开发人员可以灵活的使用函数满足各种复杂多变应用场景。
定义:ReentrantLock 是一个可重入且独占式的锁,它具有与使用 synchronized 监视器锁相同的基本行为和语义,但与 synchronized 关键字相比,它更灵活、更强大,增加了轮询、超时、中断等高级功能。
ReentrantLock,顾名思义,它是支持可重入锁的锁,是一种递归无阻塞的同步机制。除此之外,该锁还支持获取锁时的公平和非公平选择。
公平性:ReentrantLock 的内部类 Sync 继承了 AQS,分为公平锁 FairSync 和非公平锁 NonfairSync。
如果在绝对时间上,先对锁进行获取的请求一定先被满足,那么这个锁是公平的,反之,是不公平的。公平锁的获取,也就是等待时间最长的线程最优先获取锁,也可以说锁获取是顺序的。
ReentrantLock 的公平与否,可以通过它的构造函数来决定。
3. ReentrantLock 基本方法 lock 与 unlock 的使用
我们使用一个之前涉及到的 synchronized 的场景,通过 lock 接口进行实现。
场景回顾:
- 创建两个线程,创建方式可自选;
- 定义一个全局共享的 static int 变量 count,初始值为 0;
- 两个线程同时操作 count,每次操作 count 加 1;
- 每个线程做 100 次 count 的增加操作。
结果预期:获取到的结果为 200。之前我们使用了 synchronized 关键字和乐观锁 Amotic 操作进行了实现,那么此处我们进行 ReentrantLock 的实现方式。
实现步骤:
- step 1 :创建 ReentrantLock 实例,以便于调用 lock 方法和 unlock 方法;
- step 2:在 synchronized 的同步代码块处,将 synchronized 实现替换为 lock 实现。
实例:
public class DemoTest{private static int count = 0; //定义count = 0private static ReentrantLock lock = new ReentrantLock();//创建 lock 实例public static void main(String[] args) {for (int i = 0; i < 2; i+