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個已經到達,正在等候
********我最先執行***********

原帖地址:http://www.cnblogs.com/liuling/p/2013-8-21-01.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章