java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java的ReentrantLock类

Java并发编程中的ReentrantLock类详解

作者:程光CS

这篇文章主要介绍了Java并发编程中的ReentrantLock类详解,ReentrantLock是juc.locks包中的一个独占式可重入锁,相比synchronized,它可以创建多个条件等待队列,还支持公平/非公平锁、可中断、超时、轮询等特性,需要的朋友可以参考下

一、ReentrantLock介绍

ReentrantLock是juc.locks包中的一个独占式可重入锁,相比synchronized,它可以创建多个条件等待队列,还支持公平/非公平锁、可中断、超时、轮询等特性。

ReentrantLock实现Lock接口实现了一个锁所需的方法,如lock()、unLock()等,在这些方法中实际上是调用继承了AQS的同步器Sync对象中的方法来实现对锁资源的获取与释放,而内部类Sync有两个子类FairSync和NonfairSync,分别对应公平锁和非公平锁。ReentrantLock默认构造器是构造非公平锁

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、ReentrantLock特性详解

1. 多条件队列

Sync对象中开放了创建AQS中条件队列ConditionObject对象的方法,并重写了isHeldExclusively()方法(通知方法signal()要用到),因此可创建条件队列实现通知等待机制。

在这里插入图片描述

2. 非公平 & 公平锁

非公平锁NonfairSync 新进来的线程会先直接与同步队列中的线程竞争CAS竞争失败则调用acquire -> tryAcquire -> nonfairTryAcquire继续竞争,再失败才会在acquire方法中后续执行加入同步队列若线程是重入这个锁,会记录重入次数,若超过int范围溢出则抛出错误

在这里插入图片描述

在这里插入图片描述

公平锁FairSync 新来的线程若同步队列为空才竞争锁,否则tryAcquire直接返回false然后进入队列排队,实现先来后到公平锁同样也会记录重入次数

在这里插入图片描述

3. 可中断

我们知道synchronized在锁竞争时是不可中断的,获取不到锁的线程会一直处于阻塞状态。

ReentrantLock调用lockInterruptibly()获取锁的过程是可以响应中断的,其内部调用的是AQS的acquireInterruptibly()方法

当收到中断信号时会退出阻塞然后抛出InterruptedException异常从而退出锁竞争。

4. 超时

调用tryLock(long timeout, TimeUnit unit)获取锁可实现超时功能,当超过时间还未获取到锁则直接抛出异常退出锁竞争

在这里插入图片描述

内部是AQS中调用LockSupport.parkNanos()超时阻塞实现的

5. 轮询

ReentrantLock的轮询特性是指可通过tryLock()方法尝试获取锁,没获取到则不阻塞直接退出,可以过会再来尝试。tryLock()调用Sync中定义的nonfairTryAcquire方法,从前面列出的源码可知没获取到则直接返回false

在这里插入图片描述

三、ReentrantLock类和synchronized关键字的区别

ReentrantLock和synchronized都是独占式可重入锁,但是它们有如下区别:

一般来说在不需要用到ReentrantLock特殊特性的时候就用synchronized,因为synchronized显然相对来说使用起来更加简洁高效

到此这篇关于Java并发编程中的ReentrantLock类详解的文章就介绍到这了,更多相关Java的ReentrantLock类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文