线程讲解(八)

在多线程程序中,很多时候需要让多个线程相互合作完成一个任务,这要求线程间能够进行协调.
例如:任务A和B是完成一项工作的两个划分,只有A任务计算出结果后,任务B才能开始计算.我们再将任务A划分为4个子任务,交给4个线程并行执行,由于子任务有大小区分,处理小任务的线程有可能很快就执行完毕了,因此该任务需要等待其他线程执行完成后,才能继续向下执行任务B;这时候我们需要用到线程障栅.

障栅

CyclicBarrier 类是一个同步辅助类,实现了一个称为障栅的集合点,在不是所有线程都到达集合点前,线程之前可以相互等待.Cyclic 的含义是“循环的,周期的”,代表该障栅在所有等待的线程到达集合点并被释放后可以循环使用.
CyclicBarrier 类比较适合于线程数量固定的情况.

CyclicBarrier 类的构造方法:
1、CyclicBarrier(int parties) //创建障栅对象;parties为需要等待的线程个数.2、CyclicBarrier(int parties,Runnable barrierAction) // barrierAction 定义最后一个进入障栅的线程要执行的动作.
CyclicBarrier 类的常用方法:
  1. int await() 在此障栅上的线程调用该方法后将等待
  2. int await(long timeout, TimeUnit unit)如果在指定时间内达到parties的数量则继续运行,否则抛出超时异常.
  3. int getParties() 障栅对象的parties个数.
  4. int getNumberWaiting() 在障栅处等待的线程个数.
  5. void reset() 重置障栅到初始状态.

在障栅的对象上可以调用 await() 方法,该方法需要放置到 try…catch…语句块中,并捕获 InterruptedException 和 BrokenBarrierException 异常.线程在完成自己的工作后调用 await() 方法等待.当最后一个线程调用 await() 方法后,将唤醒所有等待线程,并继续该障栅后的工作.

倒计时门闩

倒计时门闩就像一个带有计数器开关的门,只有在门前等待的线程到达一定数量时,门闩才会打开,线程才可以继续执行.
倒计时门闩由 CountDownLatch 类实现,该类从 Object 继承而来,可以通过一个给定的值进行初始化,通常在同步状态中保存的是当前的计数值,线程调用 await() 方法等待;方法 countDown() 会导致计数值递减,当计数值为零时,所有的倒计时门闩范围内的等待线程的阻塞状态将解除.

CountDownLatch 类的构造方法:

CountDownLatch(int count)
其中,count 为初始计数,必须为正数,否则将抛出 IllegalArgumentException 异常.

CountDownLatch 类常用的方法:
  1. public void await() //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
  2. public boolean await(long timeout, TimeUnit unit) //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
  3. public void countDown() { };//将count值减1

信号量

信号量机制通常用于限制对于某个资源同时访问的线程数量.
信号量机制是一种典型的同步机制,可以用于解决常用的线程同步问题.
在 Java 并发库中,类 Semaphore 可以实现信号量机制,其定义如下:
public class Semaphore extends Object implements Serializable
信号量管理了一个许可集合,可以通过方法 acquire() 获取一个许可,如果没有许可则可以等待.通过方法 release() 可以释放一个许可.

它的构造方法如下:

Semaphore(int permits) // 用给定的许可数创建一个 Semaphore 对象.
Semaphore(int permits,boolean fair) // 设置许可分配策略:公平分配/非公平分配

Semaphore 类常用的方法
  1. acquire() 获取一个许可,如果没有许可可以获取,则阻塞.
  2. void acquire(int permits) 获取permits个许可,如果没有许可可以获取,则阻塞.
  3. void acquireUninterruptibly() 从此信号量中获取许可,在有可用的许可前将其阻塞.
  4. int availablePermits() 获得可用的许可数
  5. int drainPermits() 获取并返回立即可用的许可数
  6. int getQueueLength() 返回等待获取许可的线程队列长度
  7. boolean hasQueuedThreads() 线程等待队列中是否有线程等待获取许可
  8. void release() 释放一个许可
  9. void release(int permits) 释放指定数量的许可

使用场景:
银行设置了4个窗口可以同时办理业务,现在有20个顾客需要办理业务,使用信号量机制可以实现这种场景.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腹黑的乌鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值