java 线程之concurrent中的常用工具 CyclicBarrier
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 线程之concurrent中的常用工具 CyclicBarrier相关的知识,希望对你有一定的参考价值。
一、CyclicBarrier
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
A、构造函数 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
public CyclicBarrier(int parties) { this(parties, null);}
demo:
1 package com.jalja.org.thread; 2 import java.util.concurrent.CyclicBarrier; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 public class LockTest { 6 public static void main(String [] args){ 7 CyclicBarrier cyclicBarrier = new CyclicBarrier(3); 8 ExecutorService executorService= Executors.newFixedThreadPool(3); 9 Runnable threadTest=null; 10 for(int i=0;i<3;i++){ 11 threadTest=new ThreadTest(cyclicBarrier); 12 executorService.execute(threadTest); 13 } 14 executorService.shutdown(); 15 } 16 } 17 class ThreadTest implements Runnable{ 18 private CyclicBarrier cyclicBarrier; 19 public ThreadTest(CyclicBarrier cyclicBarrier){ 20 this.cyclicBarrier=cyclicBarrier; 21 } 22 public void run() { 23 try { 24 Thread.sleep((long)(Math.random()*10000)); 25 System.out.println(Thread.currentThread().getName()+"开始执行"); 26 cyclicBarrier.await(); 27 }catch (Exception e){ 28 e.printStackTrace(); 29 } 30 System.out.println(Thread.currentThread().getName()+"执行结束"); 31 } 32 }
B、构造函数 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; }
demo: 如果在构造CyclicBarrier对象的时候传了一个Runnable对象进去,则每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable。如果把上面的例子改成下面这样:
1 package com.jalja.org.thread; 2 import java.util.concurrent.CyclicBarrier; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 public class LockTest { 6 public static void main(String [] args){ 7 CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() { 8 public void run() { 9 System.out.println(Thread.currentThread().getName()+"======"); 10 try { 11 Thread.sleep((long)(Math.random()*10000)); 12 }catch (Exception e){ 13 e.printStackTrace(); 14 } 15 System.out.println(Thread.currentThread().getName()+"======>"); 16 } 17 }); 18 ExecutorService executorService= Executors.newFixedThreadPool(3); 19 Runnable threadTest=null; 20 for(int i=0;i<3;i++){ 21 threadTest=new ThreadTest(cyclicBarrier); 22 executorService.execute(threadTest); 23 } 24 executorService.shutdown(); 25 } 26 } 27 class ThreadTest implements Runnable{ 28 private CyclicBarrier cyclicBarrier; 29 public ThreadTest(CyclicBarrier cyclicBarrier){ 30 this.cyclicBarrier=cyclicBarrier; 31 } 32 public void run() { 33 try { 34 Thread.sleep((long)(Math.random()*10000)); 35 System.out.println(Thread.currentThread().getName()+"开始执行"); 36 cyclicBarrier.await(); 37 }catch (Exception e){ 38 e.printStackTrace(); 39 } 40 System.out.println(Thread.currentThread().getName()+"执行结束"); 41 } 42 }
结果:
pool-1-thread-2开始执行 pool-1-thread-3开始执行 pool-1-thread-1开始执行 pool-1-thread-1====== pool-1-thread-1======> pool-1-thread-1执行结束 pool-1-thread-2执行结束 pool-1-thread-3执行结束
以上是关于java 线程之concurrent中的常用工具 CyclicBarrier的主要内容,如果未能解决你的问题,请参考以下文章
Java 7 Concurrency Cookbook 翻译 第一章 线程管理之二
Java 7 Concurrency Cookbook 翻译 第一章 线程管理之六