并发工具类详解

什么是并发工具类

思考一下?

多线程直接怎么相互协作?

  • synchronizd(同步块,最简单最原始的办法):把其他多余的线程都卡住,让大家串行执行
  • Wait/notify(作用在线程,在执行过程中主动等待挂起,等待其他线程给他通知notify)
  • Lock/condition(作用在对象,显式的锁配合new出来的Condition对线程之间来做协调)

这些都是比较朴素的,线程之间相互协作的一种方式。(因为他不能做到我们所谓的定量,只能做定性)

因为显式的加锁操作跟实际业务杂糅到一起,使得代码看起来比较复杂。所以就创建了并发工具类。方便调用。

但更复杂的,需要这些线程满足某些条件(数量,时间)。比如:

  • 我们需要控制实际并发访问资源的并发数量
  • 我们需要多个线程在某一时间同时开始运行
  • 我们需要指定数量线程到达某个状态再继续处理

AQS(AbstractQueuedSynchronizer)

  • 队列同步器,它是构建锁或者其他同步组件的基础

如:(Semaphore、CountDownLatch、ReentrantLock、ReentrantReadWriteLock),是JUC并发包的核心基础组件,抽象了竞争的资源和线程队列

  • AbstractQueuedSynchronizer:抽象队列式的同步器
  • 两种资源共享方式:独占|共享,子类负责实现公平OR非公平。

Semaphore - 信号量

使用场景:同一时间控制并发线程数

  • 准入数量N,N=1则等同于独占锁(即Synchronized)
  • 相当于Synchronized的进化版

信号量的其他好处:

当别的接口或者系统调用我们时,在不知道其他服务会用多少个线程或者线程池来调用我们时,可以在我们的入口增加信号量来控制,从而保护我们的服务。

CountDownLatch

阻塞主线程,N个子线程满足条件时主线程继续。

场景:Master线程等待Worker线程把任务执行完。

示例:等所有人干完手上的活儿,一起去吃饭。

示例:

CyclicBarrier

场景:

任务执行到一定阶段,等待其他任务对齐,阻塞N个线程时所有线程被唤醒继续

示例:

等待所有人都到达,在一起开吃。

补充:

  • 不是主线程await,而是各个子线程await。
  • 当第N(参数:parties)个Barrier调用了await,那么整体信号的数量达到了N个,这N那大家的await就会被唤醒,继续接着往下走。

CountDownLatch和CyclicBarrier的比较

构造函数的第二个参数:barrierAction参数是达到聚合点时,要继续执行的内容。

Future/FutureTask/CompletableFuture

Future: 设置超时时间去调用get()

FutureTask:可以封装成一个有返回值的。

  • 需要在当前线程里等待
  • 最终还是把一个异步调用,转换成了一个同步的获取结果的一个过程
  • 实际场景应用型有待提高
  • Future.get()能hold住异常,然后再吐出来。但不能进行异常回调。

CompletableFuture:

  • 通过回调的方式拿到异步线程执行的结果。
  • 拿到异步的结果以后,需要进一步的对结果进行变换、转换、对多个线程的结果进行组合封装
  • 多个线程执行,某些线程抛出异常,可以进行回调

总结:

基本上把这三个工具类用熟了,在很多时候,我们去控制多个线程相互之间的协作的时候,就不需要去使用显式的锁,显式的那些并发控制的手段了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值