Java8 ReentrantLock 源码分析

本文介绍了Java8中的ReentrantLock,详细分析了其可重入特性、公平与非公平策略,并对比了它与synchronized的区别。文章探讨了ReentrantLock的源码,包括构造函数、NonfairSync和FairSync的实现,以及如何通过AQS来管理同步状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、ReentrantLock 概述

1.1 ReentrantLock 简介

故名思义,ReentrantLock 意为可重入锁,那么什么是可重入锁呢?可重入意为一个持有锁的线程可以对资源重复加锁而不会阻塞。比如下面这样:

    public synchronized void f1() {
   
   
        f2();
    }

    private synchronized void f2() {
   
    }

ReentrantLock 除了支持可重入以外,还支持定义公平与非公平策略,默认情况下采用非公平策略。公平是指等待时间最长的线程会优先获取锁,也就是获取锁是顺序的,可以理解为先到先得。

公平锁保证了锁的获取按照 FIFO(先进先出)原则,但是需要大量的线程切换。非公平锁虽然减少了线程之间的切换增大了其吞吐量,但是可能会造成线程“饥饿”。

1.2 使用方式

    public void f1() {
   
   
        ReentrantLock lock = new ReentrantLock();
        try {
   
   
            lock.lock();
            // ...
        } finally {
   
   
            lock.unlock();
        }
    }

synchronized 不同,使用 ReentrantLock 必须显示的加锁与释放锁。

1.3 与 synchronized 对比

相同点:

  • 可重入,同一线程可以多次获得同一个锁
  • 都保证了可见性和互斥性

不同点:

  • ReentrantLock 可响应中断、可轮回,为处理锁的不可用性提供了更高的灵活性,synchronized 不可以响应中断
  • ReentrantLock 是 API 级别的,synchronized 是 JVM 级别(JVM 内置属性)的,因此内置锁可以与特定的栈帧关联起来
  • ReentrantLock 可以实现公平锁,切可以实现带有时间限制的操作
  • ReentrantLock 通过 Condition 可以绑定多个条件

二、源码分析

了解了 ReentrantLock 的基本概念后,接下来就一起来看源码吧。其实 ReentrantLock 内的源码并不多,原因在于很多源码都在 AbstractQueuedSynchronizer 中,因此想要了解 ReentrantLock 源码的小伙伴需要先行了解下 AQS。

后面会给大家推荐几篇关于 AQS 源码介绍的文章,有兴趣的可以自行了解,或者到我的 GitHub 去查下相应的源码记录。点我前往 GitHub

2.1 构造函数

默认构造函数

    public ReentrantLock() {
   
   
        sync = new NonfairSync();
    }

有参构造函数

    public ReentrantLock(boolean fair) {
   
   
        sync = fair ? new FairSync() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值