java并發編程之CyclicBarrier

jopen 9年前發布 | 16K 次閱讀 Java開發 CyclicBarrier

一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程后可以重用,所以稱它為循環 的 barrier。 


CyclicBarrier 支持一個可選的 Runnable 命令,在一組線程中的最后一個線程到達之后(但在釋放所有線程之前),該命令只在每個屏障點運行一次。若在繼續所有參與線程之前更新共享狀態,此屏障操作 很有用。 
 
CountDownLatch : 一個線程(或者多個), 等待另外N個線程完成某個事情之后才能執行。 CyclicBarrier       : N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。

這樣應該就清楚一點了,對于CountDownLatch來說,重點是那個“一個線程”, 是它在等待, 而另外那N的線程在把“某個事情”做完之后可以繼續等待,可以終止。而對于CyclicBarrier來說,重點是那N個線程,他們之間任何一個沒有完成,所有的線程都必須等待。

    package com.lala.shop;

import java.util.Random;  
import java.util.concurrent.BrokenBarrierException;  
import java.util.concurrent.CyclicBarrier;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.TimeUnit;  

/** 
 *  這里演示了一個例子:五個人一同去買 襯衫、褲子、鞋子。 
 *  所有人必須先全部買完襯衫,然后才能去買褲子,全部買完褲子之后,在去買鞋子,全部買完鞋子之后,事情執行完成 
 */  
public class CyclicBarrierDemo   
{  
    public static void main(String[] args)   
    {  
        CyclicBarrier cb = new CyclicBarrier(5, new Runnable(){  
            public void run()  
            {  
                System.out.println("人已經到齊,準備下一步...");  
            }  
        });  
        ExecutorService runner = Executors.newFixedThreadPool(5);  
        runner.submit(new Shopping("李大嘴", cb));  
        runner.submit(new Shopping("白展堂", cb));  
        runner.submit(new Shopping("郭芙蓉", cb));  
        runner.submit(new Shopping("佟湘玉", cb));  
        runner.submit(new Shopping("呂秀才", cb));  
        runner.shutdown();  
    }  
}  

class Shopping implements Runnable  
{  
    private String user;  
    private CyclicBarrier cb;  

    public Shopping(String user, CyclicBarrier cb)  
    {  
        this.user = user;  
        this.cb = cb;  
    }  

    public void run()  
    {  
        try   
        {  
            long shirtTime = getRandomTime();  

            TimeUnit.SECONDS.sleep(shirtTime);  

            System.out.println(user + "買完襯衫,花了時間:" + shirtTime);  

            cb.await();  

            long pantsTime = getRandomTime();  

            TimeUnit.SECONDS.sleep(pantsTime);  

            System.out.println(user + "買完褲子,花了時間:" + pantsTime);  

            cb.await();  

            long shoseTime = getRandomTime();  

            TimeUnit.SECONDS.sleep(shoseTime);  

            System.out.println(user + "買完鞋子,花了時間:" + shoseTime);  

            cb.await();  

            System.out.println(user + "東西已經買齊了,回家");  

        } catch (InterruptedException | BrokenBarrierException e)   
        {  
            e.printStackTrace();  
        }  
    }  

    private long getRandomTime()  
    {  
        return new Random().nextInt(9) + 1;  
    }  
}  </pre><br />

輸出結果為:


呂秀才買完襯衫,花了時間:1
白展堂買完襯衫,花了時間:1
佟湘玉買完襯衫,花了時間:3
李大嘴買完襯衫,花了時間:8
郭芙蓉買完襯衫,花了時間:9
人已經到齊,準備下一步...
白展堂買完褲子,花了時間:4
佟湘玉買完褲子,花了時間:4
呂秀才買完褲子,花了時間:5
郭芙蓉買完褲子,花了時間:8
李大嘴買完褲子,花了時間:9
人已經到齊,準備下一步...
呂秀才買完鞋子,花了時間:1
白展堂買完鞋子,花了時間:2
佟湘玉買完鞋子,花了時間:7
郭芙蓉買完鞋子,花了時間:8
李大嘴買完鞋子,花了時間:8
人已經到齊,準備下一步...
李大嘴東西已經買齊了,回家
呂秀才東西已經買齊了,回家
白展堂東西已經買齊了,回家
郭芙蓉東西已經買齊了,回家
佟湘玉東西已經買齊了,回家

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!