`
longzhun
  • 浏览: 371682 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ReentrantLock(二)

 
阅读更多

ReentrantLock是一个互斥的同步器,其实现了接口Lock,里面的功能函数主要有:
1. ‍lock() -- 阻塞模式获取资源
2. ‍lockInterruptibly() -- 可中断模式获取资源
3. ‍tryLock() -- 尝试获取资源
4. tryLock(time) -- 在一段时间内尝试获取资源
5. ‍unlock() -- 释放资源

ReentrantLock实现Lock有两种模式即公平模式和不公平模式
Concurrent包下的同步器都是基于AQS框架,在ReentrantLock里面会看到这样三个类
-----------------------------------------------------------------------
static abstract class Sync extends AbstractQueuedSynchronizer {
    abstract void lock();
    final boolean nonfairTryAcquire(int acquires) { ... }
    protected final boolean tryRelease(int releases) { ... }
}
-----------------------------------------------------------------------
final static class NonfairSync extends Sync {
    protected final boolean tryAcquire(int acquires) { ... }
    final void lock() { ... }
}
-----------------------------------------------------------------------
final static class FairSync extends Sync {
    final void lock() { ... }
    protected final boolean tryAcquire(int acquires) { ... }
}
-----------------------------------------------------------------------
再回归到ReentrantLock对Lock的实现上
0. ‍ReentrantLock实例化
   ReentrantLock有个属性sync,实际上对Lock接口的实现都是包装了一下这个sync的实现
   如果是公平模式则创建一个FairSync对象,否则创建一个NonfairSync对象,默认是不公平模式
1. lock() 调用sync.lock()
   公平模式下:直接走AQS的acquire函数,此函数的逻辑走一次tryAcquire,如果成功
   线程拜托同步器的控制,否则加入NODE链表,进入acquireQueued的tryAcquire,休眠,被唤醒的轮回
   不公平模式下和公平模式下逻辑大体上是一样的,不同点有两个:
   a. 在执行tryAcquire之前的操作,不公平模式会直接compareAndSetState(0, 1)原子性的设置AQS的资源
   0表示目前没有线程占据资源,则直接抢占资源,不管AQS的NODE链表的FIFO原则
   b. tryAcquire的原理不一样,不公平模式的tryAcquire只看compareAndSetState(0, 1)能否成功
   而公平模式还会加一个条件就是此线程对于的NODE是不是NODE链表的第一个
   c. 由于tryAcquire的实现不一样,而公平模式和不公平模式在lock期间走的逻辑是一样的(AQS的acquireQueued的逻辑)
   d. 对于一个线程在获取到资源后再调用lock会导致AQS的资源做累加操作,同理线程要彻底的释放资源就必须同样
   次数的调用unlock来做对应的累减操作,因为对应ReentrantLock来说tryAcquire成功一个必须的条件就是compareAndSetState(0, 1)
   e. 由于acquireQueued过程中屏蔽了线程中断,只是在线程拜托同步器控制后,如果记录线程在此期间被中断过则标记线程的
   中断状态
2. ‍lockInterruptibly() 调用sync.acquireInterruptibly(1),上一篇文章讲过AQS的核心函数,这个过程和acquireQueued
   是一样的,只不过在阻塞期间如果被标记中断则线程在park期间被唤醒,然后直接退出那个轮回,抛出中断异常
   由于公平模式和不公平模式下对tryAcquire的实现不一样导致‍lockInterruptibly逻辑也是不一样
3. tryLock() 函数只是尝试性的去获取一下锁,跟tryAcquire一样,这两种模式下走的代码一样都是公平模式下的代码
4. tryLock(time) 调用sync.tryAcquireNanos(time),上一篇文章讲过AQS的核心函数,这个过程和acquireQueued一样,
   a. 在阻塞前会先计算阻塞的时间,进入休眠
   b. 如果被中断则会判断时间是否到了
      1. 如果没到则且被其他线程设置了中断标志,退出那个轮回,抛出中断异常,如果没有被设置中断标记则是前一个线程
      释放了资源再唤醒了它,其继续走那个轮回,轮回中,如果tryAcquire成功则摆脱了同步器的控制,否则回到a
      2. 如果时间到了则退出轮回,获取资源失败
5. ‍unlock() 调用sync.release(1),上一篇文章讲过AQS的核心函数,release函数会调用Sync实现的tryRelease函数来判断
   释放资源是否成功,即Sync.tryRelease函数,其逻辑过程是
   a. 首先判断目前占据资源的线程是不是调用者,如果不是会抛出异常IllegalMonitorStateException
   b. 如果是则进行AQS资源的减1逻辑,如果再减1后AQS资源变成0则表示调用线程测得放弃了此锁,返回给release的值的TRUE,
   release会唤醒下一个线程
-----------------------------------------------------------------------
整体来看ReentrantLock互斥锁的实现大致是
1. 自己实现AQS的tryAcquire和tryRelease逻辑,tryAcquire表示尝试去获取锁,tryRelease表示尝试去释放锁
2. ReentrantLock对lock(),trylock(),trylock(time),unlock()的实现都是使用AQS的框架,然后AQS的框架又返回调用
ReentrantLock实现的tryAcquire和tryRelease来对线程是否获取锁和释放锁成功做出依据判断

分享到:
评论

相关推荐

    Lock、Synchoronized和ReentrantLock的使用

    二、ReentrantLock ReentrantLock 是 Java 5.0 中引入的一种同步机制,它提供了多样化的同步,包括时间限制的同步、可Interrupt 的同步等。ReentrantLock 的性能比 Synchronized 略微差一点,但是在资源竞争激烈的...

    ReentrantLock与synchronized

    **二、ReentrantLock** 1. **类库特性**: - `ReentrantLock`是Java并发包`java.util.concurrent.locks`中的类,提供了比`synchronized`更灵活的锁定机制。 - 它是可重入的,即一个线程可以多次获取同一锁,不会...

    ReentrantLock源码分析

    #### 二、ReentrantLock的主要功能 ReentrantLock提供了多种锁获取方式,包括但不限于: - `lock()`:无条件地尝试获取锁,如果锁已被其他线程占用,则当前线程会阻塞直至获得锁。 - `lockInterruptibly()`:与`lock...

    ReentrantLock 与 synchronized 简介

    #### 二、synchronized 关键字 `synchronized`关键字是Java提供的内置同步机制之一。它提供了一种简单的、面向对象的方式来实现线程间的同步操作。 1. **基本概念**:`synchronized`关键字可以作用于方法或代码块,...

    ReentrantLock源码详解--公平锁、非公平锁

    第二个构造方法可以自己决定使用公平锁还是非公平锁。 ReentrantLock的lock()方法是通过调用sync属性的lock()方法实现的,sync是公平锁或非公平锁的实例。如果是公平锁,会调用FairSync的lock()方法,否则调用...

    7、深入理解AQS独占锁之ReentrantLock源码分析(1).pdf

    ### 二、AQS原理分析 #### 2.1 AQS概述 AQS提供了一个内部类Sync,该类继承自AQS,并负责处理同步器的所有调用。它将各种同步器的行为抽象成一系列方法,如tryAcquire()、tryRelease()等,这些方法可以根据具体的...

    ReentrantLock源码解析(二)

    《ReentrantLock源码解析(二)》 在Java并发编程中,ReentrantLock是一个重要的同步工具类,它提供了一种比synchronized更细粒度的锁控制机制。本文主要探讨ReentrantLock的内部实现,特别是其数据结构和关键方法...

    详解java并发之重入锁-ReentrantLock

    二、ReentrantLock 的锁机制 ReentrantLock 的锁机制是基于 AQS(Abstract Queued Synchronizer)的,AQS 是 Java 中的一个同步器框架。ReentrantLock 使用了 AQS 来实现锁机制。 ReentrantLock 的锁机制可以分为...

    Java多线程并发编程(互斥锁Reentrant Lock)

    二、ReentrantLock 的特点 1. 互斥锁:ReentrantLock 是一种互斥锁,在同一时间只能被一个线程所占有,在被持有后并未释放之前,其他线程若想获得该锁只能等待或放弃。 2. 可重入锁:ReentrantLock 是可重入锁,即...

    剑指Offer(第二版)笔记.docx

    《剑指Offer(第二版)》是一本针对Java程序员面试的经典书籍,涵盖了众多面试中常见的问题和编程技巧。其中,Singleton模式是常被考察的设计模式之一。Singleton模式的主要目的是确保一个类只有一个实例,并提供全局...

    JavaLock与Condition的理解Reentran

    **二、Condition条件对象** Condition接口是ReentrantLock的重要组成部分,它提供了比synchronized关键字的wait()和notify()更强大的控制能力。每个ReentrantLock实例都有一个默认的Condition,通过`newCondition()...

    java多线程编程(第二版)

    Java提供了多种同步工具,如synchronized关键字、wait()和notify()方法、ReentrantLock、Semaphore、CyclicBarrier以及CountDownLatch等。synchronized关键字可以保证在同一时刻只有一个线程访问特定的代码块,防止...

    Java并发编程:设计原则与模式(第二版)-3

    2. **并发控制**:Java提供了多种并发控制机制,如synchronized关键字、volatile变量、java.util.concurrent包下的锁和同步工具类(如ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier)。这些机制用于解决...

    java锁详解.pdf

    二、ReentrantLock 锁 1. 锁的原理:ReentrantLock 锁是基于 AQS(AbstractQueuedSynchronizer)机制来实现的。 2. 锁的分类:ReentrantLock 锁可以分为公平锁和非公平锁两种。 3. 公平锁:公平锁是 ReentrantLock ...

    Java课件第二章ppt

    Java提供了多种同步机制,如synchronized关键字、Lock接口(ReentrantLock等)、Semaphore信号量、CountDownLatch计数器以及CyclicBarrier屏障等。 6. **线程守护程序**:守护线程是一种特殊的线程,当所有非守护...

    尚硅谷大厂面试题第二季周阳主讲整理笔记

    - **java.util.concurrent.locks** 包含锁相关的接口和实现,如ReentrantLock,提供可中断和公平锁特性。 【volatile关键字】 volatile是Java中的轻量级同步机制,它保证了变量的可见性和禁止指令重排序,但不保证...

    【BAT必备】并发编程锁面试题

    #### 二、Java中的锁实现 **2.1 synchronized关键字详解** - **基本语法**:synchronized可以修饰方法或者代码块。 - 修饰方法:所有调用该方法的线程都必须获取该对象的锁。 - 修饰代码块:指定一个对象作为锁...

    实战Java高并发程序设计第二版随书代码

    《实战Java高并发程序设计》第二版是一本深入探讨Java多线程和并发编程的书籍。这本书涵盖了Java并发编程的核心概念和技术,旨在帮助开发者在实际项目中高效地处理高并发场景。随书附带的代码提供了丰富的示例,以便...

    尚硅谷大厂高频面试题第二季

    - **Lock接口及其实现类**:ReentrantLock的使用方式。 #### 3.3 并发工具类 - **线程池**:ExecutorService接口、ThreadPoolExecutor类的配置参数。 - **CountDownLatch**:等待一组操作完成的通知机制。 - **...

Global site tag (gtag.js) - Google Analytics