细节爆炸!并发编程的半壁江山——AQS详解
千呼万唤始出来,终于写到AQS这个一章了,其实为了写这一章,前面也是做了很多地铺垫,比如之前的
深度理解volatile关键字 线程之间的协作(等待通知模式) JUC 常用4大并发工具类 CAS 原子操作 显示锁 了解LockSupport工具类
这些文章其实都是为了让大家理解AQS而写的铺垫,就像吃东西需要一口一口的吃一样
AQS概述及其实现类:AQS,是AbstractQuenedSynchronizer的缩写,中文名称为抽象的队列式同步器,是java并发编程这一块的半壁江山,这个类存在于在java.util.concurrent.locks包,AQS定义了一套多线程访问共享资源的同步器框架 , 许多同步类实现都依赖于它,比如之前写的显示锁ReentrantLock,,读写锁ReentrantReadWriteLock,JUC的四大并发工具类中的Semaphore,CountDownLatch,线程池暂时还没写之后再写
文章插图
在JDK1.7之前,FutureTask,应该也是继承了AQS来实现的,但是1.8之后就改变了
文章插图
但是实现思想应该没有太大改变,,所以说AQS是并发编程的半壁江山
核心思想:如果被请求的共享资源空闲 , 则将当前请求资源的线程设置为有效的工作线程 , 并将共享资源设置为锁定状态 , 如果被请求的共享资源被占用 , 那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制 , 这个机制AQS是用CLH队列锁实现的 , 即将暂时获取不到锁的线程加入到队列中 。
CLH(Craig , Landin , and Hagersten)队列是一个虚拟的双向队列 , 虚拟的双向队列即不存在队列实例 , 仅存在节点之间的关联关系 。 AQS是将每一条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node) , 来实现锁的分配 。
其实在我理解来说,AQS就是基于CLH队列 , 用volatile修饰共享变量state,来保证变量的可见性 , 线程通过CAS去改变状态符,保证状态的原子性 , 成功则获取锁成功 , 失败则进入等待队列 , 等待被唤醒 。
【细节爆炸!并发编程的半壁江山——AQS详解】注意:AQS是自旋锁:在等待唤醒的时候 , 经常会使用自旋(while(!cas()))的方式 , 不停地尝试获取锁 , 直到被其他线程获取成功
框架:
文章插图
通过这个图得知 , AQS维护了一个volatile int state和一个FIFO线程等待队列 , 多线程争用资源被阻塞的时候就会进入这个队列 。 state就是共享资源 , 其访问方式有如下三种:getState();setState();compareAndSetState();
AQS 定义了两种资源共享方式:1.Exclusive:独占 , 只有一个线程能执行 , 如ReentrantLock2.Share:共享 , 多个线程可以同时执行 , 如Semaphore、CountDownLatch、ReadWriteLock , CyclicBarrier
不同的自定义的同步器争用共享资源的方式也不同 。
AQS底层使用了模板方法模式同步器的设计是基于模板方法模式的,如果不了解的可以去看看模板方法设计模式,之前在写设计模式的六大设计原则的时候也说了,看看设计模式有助于理解源码,如果需要自定义同步器一般的方式是这样:
- 使用者继承AbstractQueuedSynchronizer并重写指定的方法 。
- 将AQS组合在自定义同步组件的实现中 , 并调用其模板方法 , 而这些模板方法会调用使用者重写的方法,就类似于我定义了一个骨架,你填充东西一样
- isHeldExclusively():该线程是否正在独占资源 。 只有用到condition才需要去实现它 。
- tryAcquire(int):独占方式 。 尝试获取资源 , 成功则返回true , 失败则返回false 。
- tryRelease(int):独占方式 。 尝试释放资源 , 成功则返回true , 失败则返回false 。
- tryAcquireShared(int):共享方式 。 尝试获取资源 。 负数表示失败;0表示成功 , 但没有剩余可用资源;正数表示成功 , 且有剩余资源 。
- tryReleaseShared(int):共享方式 。 尝试释放资源 , 如果释放后允许唤醒后续等待结点返回true , 否则返回false 。
- 高像素|加持高像素只为解析力?vivo S7丛林秘境展对样张细节的要求更严苛
- 用心|用心网友制作了一加9 Pro渲染图:细节程度堪比官方
- 选对|为何都说这次OriginOS的方向选对了?来看下这些细节就知道了
- Store|苹果将在韩国开设第二家Apple Store直营店 并发布纪念壁
- 刘作虎|一加9系列更多细节曝光,刘作虎也玩起了“三机齐发”
- Linux(服务器编程):百万并发服务器系统参数调优
- 参数|外行看参数内行看细节,新手能牢记这四点,你也算半个内行了
- 并发容器ConcurrentHashMap
- 华为Mate40系列细节曝光,90Hz高刷+红外测温
- 为什么 Redis 单线程能支撑高并发?