標籤:
一個同步輔助類,它允許一組線程互相等待,直到到達某個公用屏障點 (common barrier point)。在涉及一組固定大小的線程的程式中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程後可以重用,所以稱它為迴圈 的 barrier。
上一篇的程式是用CountDownLatch實現的,現在用CyclicBarrier改寫試試
package thread.thread;import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * ClassName:CountDownLatchTest <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2015年7月30日 下午2:04:07 <br/> * * @author chiwei * @version * @since JDK 1.6 * @see */public class CyclicBarrierTest {public static void main(String[] args) {ThreadPoolExecutor poolExe = new ThreadPoolExecutor(100, 1000, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(100));int count = 10;// 考試開始鈴聲響起,考試開始final CountDownLatch examBegin = new CountDownLatch(1);// 單個考生,考試結束交卷final CyclicBarrier student = new CyclicBarrier(count+1);// 一個考場10位考生for (int i = 0; i < count; i++) {Runnable runnable = new Runnable() {public void run() {try {System.out.println("考生" + Thread.currentThread().getName() + "在等待考試開始的鈴聲響起");examBegin.await();System.out.println("考生聽到鈴聲" + Thread.currentThread().getName() + "開始答題");Thread.sleep((long) (Math.random() * 100));//答題過程,真正的商務邏輯處理部分System.out.println("考生" + Thread.currentThread().getName() + "交卷");student.await();} catch (Exception e) {e.printStackTrace();}}};poolExe.execute(runnable); // 運動員開始任務}try {// 答題時間Thread.sleep((long) (Math.random() * 10000));System.out.println("考場" + Thread.currentThread().getName() + "開始鈴聲即將響起");examBegin.countDown();System.out.println("考場" + Thread.currentThread().getName() + "考試開始鈴聲響起");student.await(); // 所有考生交卷System.out.println("考場" + Thread.currentThread().getName() + "考試結束");} catch (Exception e) {e.printStackTrace();}poolExe.shutdown();}}CountDownLatch的構造方法的參數count值是調用countDown的數量,而CyclicBarrier的數量是await,所以加1
考生pool-1-thread-1在等待考試開始的鈴聲響起考生pool-1-thread-2在等待考試開始的鈴聲響起考生pool-1-thread-6在等待考試開始的鈴聲響起考生pool-1-thread-7在等待考試開始的鈴聲響起考生pool-1-thread-5在等待考試開始的鈴聲響起考生pool-1-thread-4在等待考試開始的鈴聲響起考生pool-1-thread-10在等待考試開始的鈴聲響起考生pool-1-thread-9在等待考試開始的鈴聲響起考生pool-1-thread-3在等待考試開始的鈴聲響起考生pool-1-thread-8在等待考試開始的鈴聲響起考場main開始鈴聲即將響起考場main考試開始鈴聲響起考生聽到鈴聲pool-1-thread-1開始答題考生聽到鈴聲pool-1-thread-2開始答題考生聽到鈴聲pool-1-thread-6開始答題考生聽到鈴聲pool-1-thread-7開始答題考生聽到鈴聲pool-1-thread-5開始答題考生聽到鈴聲pool-1-thread-4開始答題考生聽到鈴聲pool-1-thread-3開始答題考生聽到鈴聲pool-1-thread-8開始答題考生聽到鈴聲pool-1-thread-9開始答題考生聽到鈴聲pool-1-thread-10開始答題考生pool-1-thread-5交卷考生pool-1-thread-4交卷考生pool-1-thread-9交卷考生pool-1-thread-2交卷考生pool-1-thread-6交卷考生pool-1-thread-1交卷考生pool-1-thread-10交卷考生pool-1-thread-7交卷考生pool-1-thread-8交卷考生pool-1-thread-3交卷考場main考試結束
從結果來看,和CountDownLatch達到同樣的效果。
注意二者的區別:
CountDownLatch是在多個線程都執行的countDown後才觸發事件,喚醒await在latch上的線程,而執行countDown的線程,在執行完countDown後繼續自己線程的工作;
CyclicBarrier是一個柵欄,用於同步所有調用await方法的線程,並且等所有線程都到了await方法的時候,它們一起返回繼續各自的工作,最外層的一個await是的計數到0,才是的所有線程得以繼續執行;因為使用CyclicBarrier的線程會阻塞在await方法上,所以線上程池中使用要格外小心,如果線程池的線程數量過少,就會發生死結
student.await();System.out.println("看看CyclicBarrier的await方法能不能把我阻塞住!");
考生pool-1-thread-1在等待考試開始的鈴聲響起考生pool-1-thread-3在等待考試開始的鈴聲響起考生pool-1-thread-2在等待考試開始的鈴聲響起考生pool-1-thread-4在等待考試開始的鈴聲響起考生pool-1-thread-5在等待考試開始的鈴聲響起考生pool-1-thread-6在等待考試開始的鈴聲響起考生pool-1-thread-7在等待考試開始的鈴聲響起考生pool-1-thread-8在等待考試開始的鈴聲響起考生pool-1-thread-9在等待考試開始的鈴聲響起考生pool-1-thread-10在等待考試開始的鈴聲響起考場main開始鈴聲即將響起考場main考試開始鈴聲響起考生聽到鈴聲pool-1-thread-1開始答題考生聽到鈴聲pool-1-thread-2開始答題考生聽到鈴聲pool-1-thread-5開始答題考生聽到鈴聲pool-1-thread-7開始答題考生聽到鈴聲pool-1-thread-10開始答題考生聽到鈴聲pool-1-thread-3開始答題考生聽到鈴聲pool-1-thread-9開始答題考生聽到鈴聲pool-1-thread-8開始答題考生聽到鈴聲pool-1-thread-6開始答題考生聽到鈴聲pool-1-thread-4開始答題考生pool-1-thread-2交卷考生pool-1-thread-10交卷考生pool-1-thread-1交卷考生pool-1-thread-3交卷考生pool-1-thread-5交卷考生pool-1-thread-4交卷考生pool-1-thread-8交卷考生pool-1-thread-7交卷考生pool-1-thread-6交卷考生pool-1-thread-9交卷看看CyclicBarrier的await方法能不能把我阻塞住!考場main考試結束看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!看看CyclicBarrier的await方法能不能把我阻塞住!
從結果來看,CyclicBarrier的await方法的確阻塞當前線程的繼續執行,只有計數到0才會得以全部繼續執行。
student.countDown();System.out.println("看看CountDownLatch的countDown方法能不能把我阻塞住!");
考生pool-1-thread-1在等待考試開始的鈴聲響起考生pool-1-thread-3在等待考試開始的鈴聲響起考生pool-1-thread-2在等待考試開始的鈴聲響起考生pool-1-thread-4在等待考試開始的鈴聲響起考生pool-1-thread-5在等待考試開始的鈴聲響起考生pool-1-thread-6在等待考試開始的鈴聲響起考生pool-1-thread-9在等待考試開始的鈴聲響起考生pool-1-thread-8在等待考試開始的鈴聲響起考生pool-1-thread-7在等待考試開始的鈴聲響起考生pool-1-thread-10在等待考試開始的鈴聲響起考場main開始鈴聲即將響起考場main考試開始鈴聲響起考生聽到鈴聲pool-1-thread-3開始答題考生聽到鈴聲pool-1-thread-2開始答題考生聽到鈴聲pool-1-thread-1開始答題考生pool-1-thread-2交卷考生聽到鈴聲pool-1-thread-10開始答題考生聽到鈴聲pool-1-thread-7開始答題考生聽到鈴聲pool-1-thread-8開始答題考生聽到鈴聲pool-1-thread-9開始答題考生聽到鈴聲pool-1-thread-6開始答題考生聽到鈴聲pool-1-thread-5開始答題考生聽到鈴聲pool-1-thread-4開始答題考生pool-1-thread-9交卷看看CountDownLatch的countDown方法能不能把我阻塞住!看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-10交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-7交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-4交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-3交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-5交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-6交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-1交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考生pool-1-thread-8交卷看看CountDownLatch的countDown方法能不能把我阻塞住!考場main考試結束
而CountDownLatch的countDown方法執行後,線程會繼續執行,不會阻塞。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
【JAVA】java中CyclicBarrier的用法,執行個體講解