`
Jen
  • 浏览: 57386 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JUC代码浅析[2]——基于AQS的锁ReentrantLock

    博客分类:
  • java
阅读更多

JUC代码浅析[2]——基于AQS的锁ReentrantLock

         ReentrantLock是使用比较普遍的一个可重入锁,它是互斥的,一个锁只能被一个线程占有。它的方法基本都是委托给继承AQSSync实现的。其中Sync有两种实现,公平和非公平。Sync使用state(通过AQS暴露的getStatesetState方法)保存线程的获取次数。总的策略为state次数为0时可以获得锁。大于0时,如果当前线程已经拥有该锁则可再次获得,否则进入AQS的调度逻辑(<JUC代码浅析——同步器AQS>中介绍)。下面为非公平ReentrantLockNonfairSync实现,

        final void lock() {

            if (compareAndSetState(0, 1))

                setExclusiveOwnerThread(Thread.currentThread());

            else

                acquire(1);

        }

如果state次数为0的话,获得成功并设置当前线程为锁的拥有者。

否则进入AQS调度,acquire(1)方法使用tryAcquire尝试获得,这里重载的tryAcquire调用的是nonfairTryAcquire方法

        final boolean nonfairTryAcquire(int acquires) {

            final Thread current = Thread.currentThread();

            int c = getState();

           //如果当前重进入数为0,有机会取得锁

            if (c == 0) {

           //获得成功并设置当前线程为锁的拥有者

                if (compareAndSetState(0, acquires)) {

                    setExclusiveOwnerThread(current);

                    return true;

                }

            }

       //如果当前线程已经拥有该锁则可再次获得

            else if (current == getExclusiveOwnerThread()) {

                int nextc = c + acquires;

                if (nextc < 0) // overflow

                    throw new Error("Maximum lock count exceeded");

                setState(nextc);

                return true;

            }

       //都不满足,则进入AQS队列等待调度

            return false;

        }

 

公平ReentrantLockFairSync实现

protected final boolean tryAcquire(int acquires) {

            final Thread current = Thread.currentThread();

            int c = getState();

       //如果当前重进入数为0,有机会取得锁

            if (c == 0) {

           //如果当前线程是第一个等待者,获得成功并设置当前线程为锁的拥有者

                if (isFirst(current) &&

                    compareAndSetState(0, acquires)) {

                    setExclusiveOwnerThread(current);

                    return true;

                }

            }

       //如果当前线程已经拥有该锁则可再次获得

            else if (current == getExclusiveOwnerThread()) {

                int nextc = c + acquires;

                if (nextc < 0)

                    throw new Error("Maximum lock count exceeded");

                setState(nextc);

                return true;

            }

       //都不满足,则进入AQS队列等待调度

            return false;

        }

 

       fairSyncNonfairSynctryRelease方法是同一个,比较简单,就是改变一下state次数,如果需要的话把拥有者线程置为null

        protected final boolean tryRelease(int releases) {

            int c = getState() - releases;

            if (Thread.currentThread() != getExclusiveOwnerThread())

                throw new IllegalMonitorStateException();

            boolean free = false;

            if (c == 0) {

                free = true;

                setExclusiveOwnerThread(null);

            }

            setState(c);

            return free;

        }

 

       公平和非公平的区别就在于,尝试进入的时候需要判断当前线程是否是队列的第一个,是第一个才能进入。这样AQS在调度的时候就会阻塞掉很多线程,性能差别就比较大。ReentrantLock只支持互斥模式,没有共享模式

 

分享到:
评论

相关推荐

    Java 多线程与并发(10-26)-JUC锁- 锁核心类AQS详解.pdf

    AQS是一个抽象的队列同步器,它基于FIFO(先进先出)队列来管理线程的排队和获取共享资源。它是实现Java并发包中锁和其他同步器的基础框架,例如ReentrantLock(可重入锁)、Semaphore(信号量)、CountDownLatch...

    狂神说JUC代码狂神说JUC代码

    在Java中,JUC(java.util.concurrent)包包含了多种并发控制和同步工具,如线程池、锁、并发容器等,这些工具使得开发者能够编写高效、安全、可维护的并发代码。以下将详细讲解其中的一些关键知识点: 1. **线程池...

    JUC AQS的加解锁.pdf

    它提供了实现排他模式(独占式)和共享模式锁的机制,被广泛应用于Java并发包中的ReentrantLock、Semaphore、CountDownLatch等组件中。 首先,AQS是一个抽象类,它的主要特点是使用一个int类型的变量(state)表示...

    Java volatile与AQS锁内存可见性

    从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性

    JUC核心类AQS的底层原理

    AQS作为Java并发工具包(JUC)中的一个核心抽象类,其设计目的是为了实现各种同步器(如锁、信号量等)。AQS主要通过三个核心组成部分来实现这些同步组件的功能: 1. **State变量及其CAS操作**:AQS维护了一个名为`...

    Java 多线程与并发(11-26)-JUC锁- ReentrantLock详解.pdf

    2. **中断支持**:ReentrantLock支持可中断的获取锁,而synchronized不支持。 3. **公平性**:ReentrantLock可配置为公平锁,而synchronized总是非公平的。 4. **锁绑定条件**:ReentrantLock可以通过newCondition()...

    juc aqs java

    juc 的aqs介绍。

    个人学习JUC代码笔记总集

    这个压缩包文件“个人学习JUC代码笔记总集”显然是一个个人的学习资源,记录了对JUC组件的理解和应用实例,特别适合已经有一定Java基础,想要深入学习并发编程的开发者。 JUC的主要目标是简化并发编程,提高多线程...

    JUC线程锁框架

    JUC中的锁机制包括ReentrantLock(可重入锁)、ReadWriteLock(读写锁)等。ReentrantLock相比synchronized具有更细粒度的控制,支持公平性和非公平性,并提供了tryLock()方法来尝试获取锁,以及lockInterruptibly...

    JUC代码收集,java高并发多线程学习

    2. **atomic**:这个包包含了一系列原子类,如`AtomicInteger`, `AtomicLong`等,它们提供了在不使用锁的情况下进行原子操作的能力,提高了并发性能。 3. **locks**:此包提供了高级锁定机制,如`ReentrantLock`和`...

    java并发编程:juc、aqs

    AQS通过内部维护一个基于链表的等待队列,有效地管理线程的同步和唤醒,从而实现锁和其他同步原语。 **AQS核心特性:** 1. **资源管理**:AQS定义了两种资源获取方式:独占和共享。独占模式下,只有一个线程能访问...

    AQS和JUC知识点讲解

    《AQS和JUC知识点详解》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)和Java Util Concurrency(JUC)是两个至关重要的概念。它们为开发高效、线程安全的多线程程序提供了强大的工具。本文将深入解析这...

    JUC(一)-AQS源码分析

    AQS源码分析一、锁的介绍1.1 乐观锁/悲观锁1.2 共享锁/独占锁1.3 公平锁/非公平锁1.4 小结二、AQS框架结构介绍2.1 类图2.2 AQS数据结构三、源码详解3.1 acquire源码详解3.2 release源码详解四、从ReentranLock看公平...

    精心整理的AQS和JUC相关的面试题.pdf【ReentrantLock】

    ⼀、ReentrantLock重⼊锁 1.1&gt; 概述 1.2&gt; 中断响应 lockInterruptibly() 1.3&gt; 锁申请等待限时 tryLock(long time, TimeUnit unit) 1.4&gt; 公平锁和⾮公平锁 1.5&gt; AQS源码解析 ⼆、Condition重⼊锁的搭配类 三、...

    这就是标题—— JUC.pdf

    JUC是什么 线程 进程 / 线程 线程状态 wait / sleep 并发 / 并行 Lock 使用Lock锁 可重入锁 公平锁 / 非公平锁 Synchronized / Lock 线程通讯 wait()、notify()和notifyAll() 虚假唤醒 Condition 定制化通信 多线程...

    JUC代码演示 Java多线程并发

    除了`synchronized`之外,Java还提供了更灵活的锁机制——`Lock`接口。`Lock`接口提供了比`synchronized`更强大的锁定机制,并且实现了更加精细的线程控制。 在示例中,使用了`ReentrantLock`类来实现自定义的锁: ...

    JUC并发工具包实例.zip

    AQS是Java并发包中的核心抽象类,它是基于FIFO队列的等待锁框架。许多并发工具,如ReentrantLock、Semaphore等,都基于AQS实现。AQS维护了一个内部状态以及一个等待线程的双端队列,通过共享或独占模式来控制资源的...

    JUC AQS(AbstractQueuedSynchronizer)

    ReentrantLock Lock 加锁过程源码分析图,AQS 源码分析

    Java——JUC

    Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....

    java并发编程-AQS和JUC实战

    ### Java并发编程-AQS和JUC实战 #### 一、ReentrantLock 重入锁 **1.1 概述** - **基本介绍**: `ReentrantLock` 是一个实现了 `Lock` 接口的可重入互斥锁,提供比 `synchronized` 更丰富的功能。与 `synchronized...

Global site tag (gtag.js) - Google Analytics