1、类 CountDownLatch
-
基本介绍
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 -
调用过程
用给定的计数初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。 -
方法摘要
void await()
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
boolean await(long timeout, TimeUnit unit)
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
void countDown()
递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
long getCount()
返回当前计数。
String toString()
返回标识此锁存器及其状态的字符串。
-
示例代码
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountdownLatchTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CountDownLatch cdOrder = new CountDownLatch(1); final CountDownLatch cdAnswer = new CountDownLatch(3); for(int i=0;i<3;i++){ Runnable runnable = new Runnable(){ public void run(){ try { System.out.println("线程" + Thread.currentThread().getName() + "正准备接受命令"); cdOrder.await(); System.out.println("线程" + Thread.currentThread().getName() + "已接受命令"); Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "回应命令处理结果"); cdAnswer.countDown(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); } try { Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将发布命令"); cdOrder.countDown(); System.out.println("线程" + Thread.currentThread().getName() + "已发送命令,正在等待结果"); cdAnswer.await(); System.out.println("线程" + Thread.currentThread().getName() + "已收到所有响应结果"); } catch (Exception e) { e.printStackTrace(); } service.shutdown(); } }
运行结果
线程pool-1-thread-3正准备接受命令 线程pool-1-thread-2正准备接受命令 线程pool-1-thread-1正准备接受命令 线程main即将发布命令 线程main已发送命令,正在等待结果 线程pool-1-thread-1已接受命令 线程pool-1-thread-2已接受命令 线程pool-1-thread-3已接受命令 线程pool-1-thread-3回应命令处理结果 线程pool-1-thread-1回应命令处理结果 线程pool-1-thread-2回应命令处理结果 线程main已收到所有响应结果
2、类CyclicBarrier
-
基本介绍
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待。 -
调用过程
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动。此时可以通过构造方法传入一个屏蔽操作。所有参与者在此 barrier 对象调用 await 方法之前,将一直等待。 -
方法摘要
int await()
在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
int await(long timeout, TimeUnit unit)
在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。
int getNumberWaiting()
返回当前在屏障处等待的参与者数目。
int getParties()
返回要求启动此 barrier 的参与者数目。
boolean isBroken()
查询此屏障是否处于损坏状态。
void reset()
将屏障重置为其初始状态。
-
示例代码
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CyclicBarrierTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CyclicBarrier cb = new CyclicBarrier(3); for(int i=0;i<3;i++){ Runnable runnable = new Runnable(){ public void run(){ try { Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候")); cb.await(); Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候")); cb.await(); Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候")); cb.await(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); } service.shutdown(); } }
-
运行结果
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候 线程pool-1-thread-1即将到达集合地点1,当前已有2个已经到达,正在等候 线程pool-1-thread-2即将到达集合地点1,当前已有3个已经到达,都到齐了,继续走啊 线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候 线程pool-1-thread-3即将到达集合地点2,当前已有2个已经到达,正在等候 线程pool-1-thread-1即将到达集合地点2,当前已有3个已经到达,都到齐了,继续走啊 线程pool-1-thread-2即将到达集合地点3,当前已有1个已经到达,正在等候 线程pool-1-thread-3即将到达集合地点3,当前已有2个已经到达,正在等候 线程pool-1-thread-1即将到达集合地点3,当前已有3个已经到达,都到齐了,继续走啊
3、区别
CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
本文详细介绍了Java并发包中的两个重要工具:CountDownLatch和CyclicBarrier。CountDownLatch用于一个线程等待多个线程完成任务;CyclicBarrier则用于一组线程互相等待至某个公共屏障点。文章通过实例代码演示了它们的使用方法,并对比了两者的不同之处。
801

被折叠的 条评论
为什么被折叠?



