jdk-CyclicBarrier(二)
来源:互联网 发布:淘宝店快速提高信誉 编辑:程序博客网 时间:2024/04/29 07:31
jdk-CyclicBarrier这一篇主要是分析了它 的源码和运行图。这一篇来看看怎么运用,毕竟都是要使用的。
上文在分析源码过程中发现有个代数的问题,在nextGeneration中会有下一代的出现,这个是否就是说它是可以重用的?不然哪会来区分一代,二代,三代呢?
例子1:次例子中重复使用了CyclicBarrier
public class TestCycB { private static int num = 3; public static void main(String[] args) throws Exception{ final CyclicBarrier cb = new CyclicBarrier(num); for(int i = 0; i < 3; i ++){ new EachThread(cb).start(); } Thread.sleep(10000); System.out.println("主线程休息够了,燥起来"); for(int i = 0; i < 3; i ++){ new EachThread(cb).start(); } }}class EachThread extends Thread{ private CyclicBarrier cb; public EachThread(CyclicBarrier cb){ this.cb = cb; } @Override public void run() { try{ Thread.sleep(2000); System.out.println(Thread.currentThread().getName()+"进入等待"); cb.await(); Thread.sleep(2000); System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来"); }catch (InterruptedException e){ e.printStackTrace(); }catch (BrokenBarrierException e1){ e1.printStackTrace(); } }}
Thread-0进入等待Thread-2进入等待Thread-1进入等待Thread-1等待结束了,执行起来Thread-0等待结束了,执行起来Thread-2等待结束了,执行起来主线程执行Thread-3进入等待Thread-5进入等待Thread-4进入等待Thread-4等待结束了,执行起来Thread-3等待结束了,执行起来Thread-5等待结束了,执行起来
例子2,使用timeout,timeout是指虽然全部线程没有完全进入,但是超过这个超时时间的话,立马执行其余线程,这些线程会抛出异常,然后继续执行.
public class TestCycB { private static int num = 3; public static void main(String[] args) throws Exception{ final CyclicBarrier cb = new CyclicBarrier(num); for(int i = 0; i < 3; i ++){ Thread.sleep(3000); new EachThread(cb).start(); } }}class EachThread extends Thread{ private CyclicBarrier cb; public EachThread(CyclicBarrier cb){ this.cb = cb; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"进入初始化"); try{ Thread.sleep(2000);//模拟初始化 System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待"); cb.await(3, TimeUnit.SECONDS); //睡3 }catch (InterruptedException e){ e.printStackTrace(); }catch (BrokenBarrierException e1){ e1.printStackTrace(); }catch (TimeoutException e2){ e2.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来"); }}
Thread-0进入初始化Thread-0初始化结束,进入等待Thread-1进入初始化java.util.concurrent.TimeoutExceptionThread-1初始化结束,进入等待at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250)Thread-0等待结束了,执行起来at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)Thread-1等待结束了,执行起来at concurrenttest.EachThread.run(TestCycB.java:40)java.util.concurrent.BrokenBarrierExceptionat java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:243)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)at concurrenttest.EachThread.run(TestCycB.java:40)Thread-2进入初始化java.util.concurrent.BrokenBarrierExceptionat java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:200)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427)at concurrenttest.EachThread.run(TestCycB.java:40)Thread-2初始化结束,进入等待Thread-2等待结束了,执行起来
例子3,自定义任务,自定义任务的执行是由最终进入的线程执行的,源码中可以看见,并且这个任务是优先于其他等待线程.
public class TestCycB { private static int num = 3; public static void main(String[] args) throws Exception{ final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() { @Override public void run() { try{ Thread.sleep(5000); }catch (Exception e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"自带任务的执行"); } }); for(int i = 0; i < 3; i ++){ new EachThread(cb).start(); } }}class EachThread extends Thread{ private CyclicBarrier cb; public EachThread(CyclicBarrier cb){ this.cb = cb; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"进入初始化"); try{ Thread.sleep(2000);//模拟初始化 System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待"); cb.await(); }catch (InterruptedException e){ e.printStackTrace(); }catch (BrokenBarrierException e1){ e1.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来"); }}
Thread-0进入初始化Thread-2进入初始化Thread-1进入初始化Thread-0初始化结束,进入等待Thread-2初始化结束,进入等待Thread-1初始化结束,进入等待Thread-2自带任务的执行Thread-0等待结束了,执行起来Thread-1等待结束了,执行起来Thread-2等待结束了,执行起来
例子4: 可以发现自带任务先执行完,最后才指向其他任务。
public class TestCycB { private static int num = 3; public static void main(String[] args) throws Exception{ final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() { @Override public void run() { try{ Thread.sleep(10000); }catch (Exception e){ e.printStackTrace(); } System.out.println("自带任务执行了"); } }); for(int i = 0; i < 3; i ++){ new EachThread(cb).start(); } }}class EachThread extends Thread{ private CyclicBarrier cb; public EachThread(CyclicBarrier cb){ this.cb = cb; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"进入初始化"); try{ System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待"); cb.await(1, TimeUnit.SECONDS); //睡3 }catch (InterruptedException e){ e.printStackTrace(); }catch (BrokenBarrierException e1){ e1.printStackTrace(); }catch (TimeoutException e2){ e2.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来"); }}
Thread-2进入初始化Thread-2初始化结束,进入等待Thread-1进入初始化Thread-1初始化结束,进入等待Thread-0进入初始化Thread-0初始化结束,进入等待自带任务执行了Thread-0等待结束了,执行起来Thread-2等待结束了,执行起来Thread-1等待结束了,执行起来
public class TestCycB { private static int num = 3; public static void main(String[] args) throws Exception{ final CyclicBarrier cb = new CyclicBarrier(num,new Runnable() { @Override public void run() { try{ Thread.sleep(6000); System.out.println("自带任务执行了:抛异常"); int j = 1 /0; }catch (Exception e){ e.printStackTrace(); } } }); for(int i = 0; i < 3; i ++){ new EachThread(cb).start(); } }}class EachThread extends Thread{ private CyclicBarrier cb; public EachThread(CyclicBarrier cb){ this.cb = cb; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"进入初始化"); try{ Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + "初始化结束,进入等待"); cb.await(); //睡3 }catch (InterruptedException e){ e.printStackTrace(); }catch (BrokenBarrierException e1){ e1.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"等待结束了,执行起来"); }}
Thread-0进入初始化Thread-2进入初始化Thread-1进入初始化Thread-2初始化结束,进入等待Thread-0初始化结束,进入等待Thread-1初始化结束,进入等待自带任务执行了:抛异常Thread-1等待结束了,执行起来Thread-2等待结束了,执行起来Thread-0等待结束了,执行起来java.lang.ArithmeticException: / by zeroat concurrenttest.TestCycB$1.run(TestCycB.java:25)at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:213)at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:355)at concurrenttest.EachThread.run(TestCycB.java:54)
最后来比较下CountDownLatch和CyclicBarrier的一些不同点。。
拿赛跑来说吧,这是个比较典型的例子。
场景1:5个人赛跑,还有一个裁判,当裁判说开始时,5个人起跑,当某一个人到达终点后,裁判按一下计数器,直至最后一个人到达,最后裁判才开始统计时间,得到每个人的时间。这个就是CountDownLatch的运用。
场景2:还是5个人赛跑,这一次没有裁判了,只规定如果5个人到达终点后,一起去喝酒这个就是CyclicBarrier的运用,此例子中没有说是否需要一起起跑,如果需要,可以加上CountDownLatch。
CountDownLatch就是一个线程等待其他线程都完成之后,再执行某些事情,强调这个。
CyclicBarrier强调线程互相等待,等待全部完成。
阅读全文
0 0
- jdk-CyclicBarrier(二)
- jdk-CyclicBarrier(一)
- JDK学习-CountDownLatch/CyclicBarrier
- JDK 源码解析 —— CyclicBarrier
- JDK并发包---(10)循环栅栏:CyclicBarrier
- jdk的CountdownLatch和CyclicBarrier的使用
- cyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- CyclicBarrier
- cyclicBarrier
- CyclicBarrier
- Android 缩略图工具
- Java面试题(一)
- Android Intent使用总结
- mysql中日期比较大小方法详解
- POJ2586 Y2K Accounting Bug(贪心)
- jdk-CyclicBarrier(二)
- new Date().getHours()转换为12小时制
- CPU和内存调优(非常全)
- ExpandableListView侧滑删除
- 利用随机森林做特征选择
- 使用 git 把远程仓库(github/码云)的代码拉到本地进行开发
- sql中in,exists的用法与区别
- MyBatis别名和settings设置
- Java程序员必须掌握的8大排序算法