JDK1.8源码学习篇一——AbstractQueuedSynchronizer学习笔记

一、引言

      最近想深入学习一下java并发的基础知识,总感觉在对java.util.concurrent一知半解,很多东西好像只有点印象,这次接着学习源码的机会来深入了解一下。那么为什么把AbstractQueuedSynchronizer这个类放在最前面呢?其实相信很多人跟我有同样的经历,首先学习的是ExecuteService线程池,然后学习里面的工厂类Executors,和其中的submit、execute方法,但是学到一半的时候,发现里面很多东西用的都是锁的概念,比如我们最常用的synchronized关键字和ReentrantLock类,这里对这个也不是很了解,然后想继续学习下去,又对ReentrantLock这个类源码学习一下,最后,最后发现其中一个很核心的类AbstractQueuedSynchronizer,学习完之后,又回过头来进行总结一下,发现这个类有很多的实现子类,都是我们常用的,那么索性先把这个类放在最前面,把其中相关的方法都学习一遍。

二、AQS详解

   首先,什么是AQS呢?AQS(AbstractQueuedSynchronizer)框架就是提供了一个自动管理同步状态、阻塞和非阻塞线程,以及等待队列的通用机制。内部主要包含了两个内部类一个是Node和ConditionObject,其中基于node节点构建了一个FIFO的队列,采用的是链表的数据结构进行存储。首先我们看下该类的主要结构:

public abstract class AbstractQueuedSynchronizer  extends AbstractOwnableSynchronizer implements java.io.Serializable {
     static final class Node {}
     public class ConditionObject implements Condition, java.io.Serializable {}
}

可以看到其中包含了两个内部类,Node主要用作数据结构,用来保存对应的节点信息。这里面我们接着看这个抽象方法中几个比较重要的方法,tryAcquire/tryRelease/tryAcquireShared/tryReleaseShared/isHeldExclusively这个5个方法,可以看到这个5个方法都是protected类型的,所以可以让子类直接去实现它,这几个方法都没有对应的方法体,因此对应的逻辑可以写在子类中。通过tryAcquire可以获取锁,而通过tryAcquire可以去直接释放锁。AOS是一个典型的模板方法设计模式的典型运用案例,AQS为一个抽象类,却没有抽象方法,所有的方法具体实现都要子类去实现。它提供了:如何让现场如队列,如何让现场出队列,现场如何等待和转移等模板方法,而子类需要做的事情,就是如何决定线程出入队列。

   protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
    protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }

    protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }

    protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }

    protected boolean isHeldExclusively() {
        throw new UnsupportedOperationException();
    }

三 AQS的原理

     AQS使用的是一个int类型的成员变量state来表示当前的同步状态,当state>0的时候表示已经获取到了锁,当state=0的时候,表示释放了锁,它共提供了3个方法getState(),setState()和compareAndSetState()来对同步的状态state进行操作,整个过程采用的是原子操作,保证安全性。

      AQS通过内置的同步队列来完成线程的排队工作,如果当前线程获取锁失败的时候,会将当前线程以及等待状态信息的构造成一个节点,加入同步队列中,同时会阻塞当前线程,当同步锁释放的时候,则会把节点中的线程唤醒,使得其获得锁。

四、ReentrantLock简介

      ReentrantLock的功能是实现代码的并发访问控制,实际上是一种排他锁,这里我们要用到的其中两个不同的锁,就NofaiSync和FairSync,就是通常所说的公平锁和非公平锁,默认的是采用非公平的锁。这里我们可以这个类的结构,其中几个几个内部类,其中Sync是一个抽象类,并且继承了AbstractQueuedSynchronizer,而

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值