11.常见并发工具原理分析

在上一篇中,我们讲了lock的出现是解决syncroinzed使用不灵活的问题,其实syncroinzed是使用wait/notify实现线程间通信,那J.U.C 里面有没有提供类似的线程通信的工具呢?我们今天就来聊下这些工具以及它的底层原理,在聊之前,我先总结成一句话:所有这些工具底层本质归结到AQS队列(同步队列)以及Condition队列(等待队列),接下来看如何印证这句话!

补充:AQS在实现独占锁的时候,state是锁标记(只有一个线程可以对次变量进行修改)!在实现共享锁的时候,state只是计数器(允许多个线程对其操作)!

并发工具1:Condition--》一个多线程协调通信的工具类,可以让某些线程一起等待某个条件(condition),只有满足条件时,线程才会被唤醒!condition 中两个最重要的方法,一个是 await,一个是 signal 方法!await:把当前线程阻塞挂起,signal:唤醒阻塞的线程!使用的方式原理也与wait/notify类似!

condition使用


Condition原理图类似wait/notify

并发工具2:CountDownLatch--》countdownlatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完毕再执行!或者可以理解为:“可以使得一组线程达到一个同步点之前阻塞”!有点类似 join 的功能,但是比 join 更加灵活!

原理:CountDownLatch使用的是AQS的共享功能!CountDownLatch 构造函数会接收一个 int 类型的参数state作为计数器的初始值,然后调用await方法,await 可以被多个线程调用,所有调用了await 方法的线程阻塞在 AQS 的阻塞队列中,等待条件满足(state == 0),将线程从队列中一个个唤醒过来。而这个时候如果执行countDown方法,每次调用都会将 state 减 1,直到state为0的时候,则调用 doReleaseShared唤醒处于 await 状态下的线程!这里需要注意一点,共享锁的释放和独占锁的释放还是有区别的,它之前会把共享锁模式下的结点状态变为PROPAGATE,处于这个状态下的节点,会对线程的唤醒进行传播!

CountDownLatch

案例分析

CountDownLatch案例

运行结果

运行结果

并发工具3:Semaphore--》可以控制同时访问的线程个数,通过 acquire 获取一个许可,如果没有就等待,通过 release 释放一个许可!本质上讲是操作系统中的信号量的概念!常用的场景:限流!

原理分析:实现一定是基于 AQS 的共享锁,创建 Semaphore 实例的时候,需要一个参数 permits,这个基本上可以确定是设置给 AQS 的 state 的,然后每个线程调用 acquire 的时候,执行 state = state - 1!release 的时候执行 state = state + 1,当然,acquire 的时候,如果 state=0,说明没有资源了,需要等待其他线程 release,具体的实现可以查看官方文档或者网上一些博主的记录,因为类似于信号量,所以比较好理解,这里就不实现了

注意点:Semaphore分公平策略和非公平策略,区别就在于是不是会先判断是否有线程在排队,然后才进行 CAS 减操作!如果有判断则是公平策略,否则是非公平策略!

semaphore的使用

并发工具4:CyclicBarrier(可循环使用的屏障)--》它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续工作。CyclicBarrier 默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 当前线程已经到达了屏障,然后当前线程被阻塞!

使用场景:当存在需要所有的子任务都完成时,才执行主任务,这个时候就可以选择使用 CyclicBarrier!

原理:CyclicBarrier 相比 CountDownLatch 来说,要简单很多,源码实现是基于 ReentrantLock 和 Condition 的组合使用。

使用案例:从不同地方导入数据,然后进行分析

数据分析
数据导入
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 周末的晚上,失联两年的老同事约我在星巴克喝咖啡,寒暄过后,他给我讲了最近的烦心事,缘由是从他上周带八岁的儿子去公园...
    河马兄简书阅读 356评论 0 0
  • 做人低调,做事高调。做人不要太刻意表现自己,把自己摆在明处,容易被人嫉妒,也容易让自己受到伤害。低调是修养,也是谦...
    曾經的笑阅读 188评论 0 3
  • 一样忙忙碌碌的早上,一样拥挤的公交。;来到公司后,发现自己无事可做。这么好的办公环境,这么好的配置,完全不知道要干...
    失控的小小阅读 227评论 0 0

友情链接更多精彩内容