java.util.concurrent包(6)——CyclicBarrier使用
CyclicBarrier是一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時CyclicBarrier很有用。因為該barrier在釋放等待線程後可以重用,所以稱它為循環的barrier。CyclicBarrier類似於CountDownLatch也是個計數器, 不同的是CyclicBarrier數的是調用了CyclicBarrier.await()進入等待的線程數, 當線程數達到了CyclicBarrier初始時規定的數目時,所有進入等待狀態的線程被喚醒並繼續。CyclicBarrier就象它名字的意思一樣可看成是個障礙, 所有的線程必須到齊後才能一起通過這個障礙。 CyclicBarrier初始時還可帶一個Runnable的參數,此Runnable任務在CyclicBarrier的數目達到後,所有其它線程被喚醒前被執行。
構造方法摘要
CyclicBarrier(int parties)
創建一個新的CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啟動,但它不會在每個barrier上執行預定義的操作。
CyclicBarrier(int parties, Runnable barrierAction)
創建一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啟動,並在啟動 barrier 時執行給定的屏障操作,該操作由最後一個進入barrier的線程執行
方法摘要
int await()
在所有參與者都已經在此barrier上調用await方法之前,將一直等待
int await(long timeout, TimeUnit unit)
在所有參與者都已經在此屏障上調用 await 方法之前,將一直等待
int getNumberWaiting()
返回當前在屏障處等待的參與者數目
int getParties()
返回要求啟動此 barrier 的參與者數目
boolean isBroken()
查詢此屏障是否處於損壞狀態
void reset()
將屏障重置為其初始狀態
例一
public class RunnerTask implements Runnable
{
private final CyclicBarrier cyclicBarrier;
private String name;
public RunnerTask(CyclicBarrier cyclicBarrier, String name)
{
super();
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}
public void run()
{
try
{
try
{
// 模擬等待
Thread.sleep(new Random().nextInt(5) * 1000);
System.out.println(name + "準備......");
cyclicBarrier.await();
System.out.println(name + "跑!");
}
catch (BrokenBarrierException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class RunnerTest
{
public static void main(String[] args)
{
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 1; i <= 5; i++)
{
new Thread(new RunnerTask(cyclicBarrier, "運動員" + i)).start();
}
}
}
運動員3準備......
運動員2準備......
運動員4準備......
運動員5準備......
運動員1準備......
運動員3跑!
運動員2跑!
運動員1跑!
運動員5跑!
運動員4跑!
例二
public class CyclicBarrierTest2
{
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() + "個已經到達,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("線程" + Thread.currentThread().getName()
+ "即將到達集合地點2,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("線程" + Thread.currentThread().getName()
+ "即將到達集合地點3,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
線程pool-1-thread-1即將到達集合地點1,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點1,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點1,當前已有2個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點2,當前已有0個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點2,當前已有1個已經到達,正在等候
線程pool-1-thread-1即將到達集合地點2,當前已有2個已經到達,正在等候
線程pool-1-thread-1即將到達集合地點3,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點3,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點3,當前已有2個已經到達,正在等候
例三
public class CyclicBarrierTest
{
public static void main(String[] args)
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3, new Runnable()
{
public void run()
{
System.out.println("********我最先執行***********");
}
});
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() + "個已經到達,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("線程" + Thread.currentThread().getName()
+ "即將到達集合地點2,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("線程" + Thread.currentThread().getName()
+ "即將到達集合地點3,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
線程pool-1-thread-1即將到達集合地點1,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點1,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點1,當前已有2個已經到達,正在等候
********我最先執行***********
線程pool-1-thread-1即將到達集合地點2,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點2,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點2,當前已有2個已經到達,正在等候
********我最先執行***********
線程pool-1-thread-1即將到達集合地點3,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點3,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點3,當前已有2個已經到達,正在等候
********我最先執行***********
原帖地址:https://www.cnblogs.com/liuling/p/2013-8-21-01.html
最後更新:2017-04-03 07:57:14
上一篇:
UNIX/Linux C 程序員需要掌握的七種武器
下一篇:
程序員眼中的編程語言和操作係統
Erlang入門(五)——補遺
Check Mysql Status
此文對你人生會有莫大好處的,建議永久保存
如何設計一個好的Windows 8應用
重讀avro文件 對文件進行簡單的mr計算
tomcat:一台機器上同時啟動兩個tomcat的注意點
在深入學習gnuradio之前你需要知道的
??????????????????????????????--?????????????????????????????????????????????????????????-??????-????????????-?????????
ORACLE A表根據B表字段更新
Jquery倒數計時按鈕—setTimeout