package a.jery; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Jery { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CyclicBarrier cb=new CyclicBarrier(5,new Runnable(){ @Override public void run() { System.out.println("人都到齐了,我们开始吧!"); try { System.out.println("...singing...singing..."); Thread.sleep((long)(Math.random()*1000)+4000);//唱4秒到5秒 System.out.println("...singing...singing..."); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("表演结束,大家回家吃饭吧!"); System.exit(0); } }); System.out.println(String.format("大家好,下面我们需要%s人合唱,有自愿者请上台", cb.getParties())); for(int i=1;i<=5;i++){ service.execute(new Runnable(){ @Override public void run() { try { Thread.sleep((long)(Math.random()*100));//为了看到效果,每个线程花费点时间 System.out.println(String.format("目前已有%s人上台", cb.getNumberWaiting())); System.out.println(String.format("。呀,有人举手了,有请%s号上台", Thread.currentThread().getId())); cb.await(); } catch (Exception e) { e.printStackTrace(); } } }); } } }
执行结果:
大家好,下面我们需要5人合唱,有自愿者请上台
目前已有0人上台
。呀,有人举手了,有请12号上台
目前已有1人上台
。呀,有人举手了,有请10号上台
目前已有2人上台
。呀,有人举手了,有请13号上台
目前已有3人上台
。呀,有人举手了,有请9号上台
目前已有4人上台
。呀,有人举手了,有请11号上台
人都到齐了,我们开始吧!
...singing...singing...
...singing...singing...
表演结束,大家回家吃饭吧!
这是一个最简单的演示,下面我们来看看循环屏障的真正好处:
package a.jery; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Jery { public static void main(String[] args) { final ExecutorService service = Executors.newCachedThreadPool(); final CyclicBarrier cb=new CyclicBarrier(5,new Runnable(){ @Override public void run() { System.out.println("人都到齐了,我们开始吧!"); try { System.out.println("...singing...singing..."); Thread.sleep((long)(Math.random()*1000)+4000);//唱4秒到5秒 System.out.println("...singing...singing..."); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("表演结束,大家回家吃饭吧!"); System.out.println("----------------"); System.out.println("大家吃好饭了吧,请唱歌的同学再次上台,我们要演奏下一首歌。"); } }); System.out.println(String.format("大家好,下面我们需要%s人合唱,有自愿者请上台", cb.getParties())); for(int i=1;i<=5;i++){ service.execute(new Runnable(){ @Override public void run() { try { Thread.sleep((long)(Math.random()*100));//为了看到效果,每个线程花费点时间 System.out.println(String.format("目前已有%s人上台", cb.getNumberWaiting())); System.out.println(String.format("。呀,有人举手了,有请%s号上台", Thread.currentThread().getId())); cb.await(); //注意此处代码须在5人都上台并演唱结束后才能执行 Thread.sleep((long)(Math.random()*100));//为了看到效果,每个线程花费点时间 System.out.println(String.format("第二首歌已有%s人上台", cb.getNumberWaiting())); System.out.println(String.format("有请%s号上台", Thread.currentThread().getId())); cb.await();//此处又可以唱歌了,这就是循环屏障和CountDownLantch的最大区别。可以循环利用 System.out.println("我擦,怎么又要唱了,老子不干了"); Thread.currentThread().interrupt(); System.out.println("有你这么用人的吗?老子拆了你舞台."); service.shutdown(); System.out.println("...bom...bom..."); } catch (Exception e) { e.printStackTrace(); } } }); } } }
执行结果:
大家好,下面我们需要5人合唱,有自愿者请上台 目前已有0人上台 。呀,有人举手了,有请11号上台 目前已有1人上台 。呀,有人举手了,有请12号上台 目前已有2人上台 。呀,有人举手了,有请9号上台 目前已有3人上台 。呀,有人举手了,有请10号上台 目前已有4人上台 。呀,有人举手了,有请13号上台 人都到齐了,我们开始吧! ...singing...singing... ...singing...singing... 表演结束,大家回家吃饭吧! ---------------- 大家吃好饭了吧,请唱歌的同学再次上台,我们要演奏下一首歌。 第二首歌已有0人上台 有请9号上台 第二首歌已有1人上台 有请12号上台 第二首歌已有2人上台 有请11号上台 第二首歌已有3人上台 有请13号上台 第二首歌已有4人上台 有请10号上台 人都到齐了,我们开始吧! ...singing...singing... ...singing...singing... 表演结束,大家回家吃饭吧! ---------------- 大家吃好饭了吧,请唱歌的同学再次上台,我们要演奏下一首歌。 我擦,怎么又要唱了,老子不干了 我擦,怎么又要唱了,老子不干了 有你这么用人的吗?老子拆了你舞台. 我擦,怎么又要唱了,老子不干了 有你这么用人的吗?老子拆了你舞台. 有你这么用人的吗?老子拆了你舞台. 我擦,怎么又要唱了,老子不干了 有你这么用人的吗?老子拆了你舞台. 我擦,怎么又要唱了,老子不干了 有你这么用人的吗?老子拆了你舞台. ...bom...bom... ...bom...bom... ...bom...bom... ...bom...bom... ...bom...bom...