线程知识学习六——并发(辅助类)
2015-10-21 11:15
323 查看
继其几篇博客线程的并发知识的了解,我们使用了synchronized和lock,我们这篇博客说实现线程并发的一些辅助类。
图中有五个辅助类,分别是:信号量,countDownLatch,CyclicBarrier、Phaser、Exchanger。
五个类各自有不同的特长。
主要方法如下:
public CountDownLatch(int count);
构造方法参数指定了计数的次数。
public void countDown();
countDown方法,当前线程调用此方法,则计数减一。
public void await() throws InterruptedException
awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0。
示例代码如下:
下面看看对应的方法。
public CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的CycleBarrier,它将在给定数量的参与者(线程)处于等待状态时候启动,并在启动barrier时执行给定的屏障操作,该操作由最后一个今日的屏障的线程执行。参数barrierAction是在启动屏障的时候执行命令,如果不执行任何操作则该参数是null。
public int await()
在所有参与者都已经在此barrier上调用 await方法之前,将一直等待。如果当前线程部署将要到达的最后一个线程将禁用它。
reset
将屏障重置为其初始化状态,如果所有参与者目前都在屏障处等待,则它们将返回,而且会抛出一个异常。
getNumberWaiting
返回当前在屏障处等待的参与者数目。
代码示例:
下篇博客继续信号量和Phaser,exchanger。
辅助类概览
都有哪些辅助类呢?我们看下图图中有五个辅助类,分别是:信号量,countDownLatch,CyclicBarrier、Phaser、Exchanger。
五个类各自有不同的特长。
CountDownLatch
CountDownLatch:在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数初始化CountDownLatch。由于调用了countDown()方法,所以在当前计数到达零之前,await方法会一直受阻塞。之后,会释放所有等待的线程,await的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用辅助类:CyclicBarrier。主要方法如下:
public CountDownLatch(int count);
构造方法参数指定了计数的次数。
public void countDown();
countDown方法,当前线程调用此方法,则计数减一。
public void await() throws InterruptedException
awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0。
示例代码如下:
import java.util.concurrent.CountDownLatch; class CountDownLatchDemo { /** * CountDownLatch:闭锁 * 在完成一组正在其他线程中执行的操作之前,它约束一个或多个线程一直等待。 * 可用于:子任务执行完成后再进行另一个操作。 */ static void test(int threadTaskNum) { final CountDownLatch answers = new CountDownLatch(threadTaskNum);//同步计数器 for (int i = 0; i < threadTaskNum; i++) { new Thread(new Runnable() { @Override public void run() { try { System.out.println("线程" + Thread.currentThread().getName() + " 开始处理任务 ..."); Thread.sleep((long) (Math.random() * 5000)); System.out.println("线程" + Thread.currentThread().getName() + " 处理完毕,汇报结果!"); answers.countDown(); } catch (Exception e) {} } }).start(); } try { answers.await();// 在所有子线程结束前保持阻塞 } catch (InterruptedException e) {} System.out.println("线程" + Thread.currentThread().getName() + "已收到所有汇报结果"); } } public class Test { public static void main(String[] args) { CountDownLatchDemo.test(3); } }
CyclicBarrier
CyclicBarrier是一个同步的辅助类,它允许一组线程互相等待,直到到达某个公告屏障点。在设计一组固定大小的线程的程序中,这些线程必须不时的相互等待,此时它很有用,因为该屏障在释放等待线程后可以重用,所以称它为循环的屏障。下面看看对应的方法。
public CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的CycleBarrier,它将在给定数量的参与者(线程)处于等待状态时候启动,并在启动barrier时执行给定的屏障操作,该操作由最后一个今日的屏障的线程执行。参数barrierAction是在启动屏障的时候执行命令,如果不执行任何操作则该参数是null。
public int await()
在所有参与者都已经在此barrier上调用 await方法之前,将一直等待。如果当前线程部署将要到达的最后一个线程将禁用它。
reset
将屏障重置为其初始化状态,如果所有参与者目前都在屏障处等待,则它们将返回,而且会抛出一个异常。
getNumberWaiting
返回当前在屏障处等待的参与者数目。
代码示例:
import java.util.concurrent.CyclicBarrier; class CyclicBarrierDemo { /** * CyclicBarrier:屏障 * 它约束一组线程必需达到某时刻,再向下执行,在没有完全达到之前保持等待 * 比如:开会,必须要等所有人都到大厅后,会议才能开始。 */ static void test(int threadNum) { // CyclicBarrier cyclicBarrier = new CyclicBarrier(3); // 构造方法可支持一个Runnable,用于在所有线程都达到后首先执行。 final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out.println("都准备好了!"); } }); for (int i = 0; i < threadNum; i++) { new Thread(new Runnable() { @Override public void run() { try { System.out.println("线程" + Thread.currentThread().getName() + " 已经准备好."); cyclicBarrier.await(); Thread.sleep((long) (Math.random() * 2000)); System.out.println("线程" + Thread.currentThread().getName() + " 处理完毕,汇报结果!"); } catch (Exception e) {} } }).start(); } } } public class Test { public static void main(String[] args) { CyclicBarrierDemo.test(3); } }
下篇博客继续信号量和Phaser,exchanger。
相关文章推荐
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- 探究在C++程序并发时保护共享数据的问题
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- ASP.NET线程相关配置
- 浅析linux环境下一个进程最多能有多少个线程
- 再谈JavaScript线程
- C#实现终止正在执行的线程
- Java线程编程中的主线程讲解