• 并发编程J.U.C之AQS剖析


     一、j.u.c简介

       在说主题AQS之前,我们有必要先来说一下J.U.C

       顾名思义J.U.C就是java.util.concurrent,java并发工具包。由我们的并发大师老爷子Doug Lea亲自操刀完成。而在这个包里,包含了我们大名鼎鼎的Lock、ConrurrentHashMap、CountDownLatch、Executor、LinkedBlockingQueue、ThreadPoolExecutor等重要的处理并发的类或者接口。当然,这些只是我听说过的一些。(此处应该有一个笑哭的表情),后续我将会带大家一一解读这些重要的并发工具。

       废话不多说,让我们一步一步剥丝抽茧,解开AQS的神秘面纱。

    二、AQS

      1.AQS概要

        AQS,全程AbstractQueuedSynchronizer--抽象队列同步器,他诞生于JDK1.5,是java中关于线程、同步的基础组件。如果对原文感兴趣的话,可以参见大师的原文:J.U.C Synchronizer Framework。既然作为基础组件,那么它便存在了大量的应用场景。

         1.1 AQS应用场景

          在此处,我们以可重入锁ReentrantLock来举例,说明AQS的内在原理。ReentrantLock关系类图如下:

          

     1 package com.jarluo.AQS;
     2 
     3 import java.util.concurrent.locks.Lock;
     4 import java.util.concurrent.locks.ReentrantLock;
     5 
     6 /**
     7  * @desc AQS应用场景之可冲入锁ReentrantLock
     8  * @author jar luo
     9  * @time 2019.5.21
    10  */
    11 public class ReentrantLockDemo {
    12 
    13     static Lock lock = new ReentrantLock();
    14 
    15     public static void main(String[] args) {
    16         lock.lock();
    17         try {
    18             System.out.println("AQS应用场景之可冲入锁ReentrantLock");
    19         } finally {
    20             lock.unlock();
    21         }
    22     }
    23 }
    AQS应用场景

         从上面的代码,我们可以看出,AQS应用起来还是很简单的,但是我们从关系类图中可以看到在ReentrantLock中维护了一个Sync内部类,同时Sync有两个子类,分别是NonFairSync和FairSync。此处我们主要对NonFairSync进行追踪(FairSync更加简单一些),可以得到以下时序图:

        

        

        通过观察AQS源码发现,AQS 包含了以下几种核心技术点:

        1.1 state

        1.2 cas原子方法

        1.3 自旋锁

        1.4 CLH变种队列

    沿着volitile状态管理-CAS原子操作-自旋锁-CLH队列进行展开

      

        

      2.锁的基本要素

        2.1 一个共享的数据来记录状态 

    二、Lock

      0.synchronized和ReentrantLock的区别

        1.关键字、一个是J.U.C

        2.释放

        局限性:不够灵活,锁释放要么执行完,要么出异常。

      1.Lock是什么

        1.1Lock是一个interface。

        1.2Lock 提供了获得锁和释放锁的方法

       2.重入锁

        2.1 ReentrantLock 重入互斥锁--表示可以重新进入的锁。

          2.1.1唯一实现了Lock接口的一个类。   

            lock.lock(),增加重入次数

            synchronized也支持重入。

            代码示例:

          2.1.2 当多个线程竞争锁的时候,其他线程怎么办?

             阻塞  

      2.2 ReentrantReadWriteLock --重入读写锁

          读->读  是共享的

          读->写  互斥

          写->写  互斥

          适用场景:读多写少的场景。

          代码示例:

    三、AQS--抽象队列同步器

      1.概念:同步工具

      2.功能:

        2.1独占->互斥

        2.2共享->读读

      3.基本实现:

        用双向链表去维护等待获得锁的线程对象

        Node节点 上节点 下节点 线程

        状态(state):锁标记

          0是无锁状态

          >=1是有锁状态(表示可以重入)

      4.CAS

        偏移量 cas(obj,offset,expect,update)

        乐观锁

        本地方法:

         

    四、Sync

      1.非公平锁--NonfairSync

        允许插队

      2.公平锁--FairSync

        不允许插队

      

    五、关系图 

      时序图

     

  • 相关阅读:
    APP与智能手表是如何通信的【本文摘抄自深圳尚锐科技】
    flash添加超链接的办法
    NPOI使用手册
    如何在 SQL Server 实例之间传输登录和密码
    CentOS 7 上部署Mono 4 和Jexus 5.6
    django models 中choices之用法举例
    django中的objects.get和objects.filter方法的区别
    Django中的Model.objects.create() 和 Model() 的区别?
    python爬虫练手项目快递单号查询
    根据现有的数据库自动生成Django model
  • 原文地址:https://www.cnblogs.com/java333/p/10872837.html
Copyright © 2020-2023  润新知