天天看點

CyclicBarrier (可循環屏障)介紹

介紹

        CyclicBarrier(可循環屏障)是一個線程同步輔助類,可用于多個線程之間互相等待,而且是可循環使用的。使用時需要在互相等待的線程中傳入同一個CyclicBarrier對象,通過調用CyclicBarrier對象的

await()

方法實作等待,在所有的線程都運作到

await()

方法處時,所有的線程等待結束,一起向下執行。CyclicBarrier執行個體化時需要傳入執行的線程數,這點與CountDownLatch(線程計數器)相同,可以看作是能重複使用的CountDownLatch。CyclicBarrier的構造方法中還可以傳入一個Runnable對象,用于所有的線程都運作到等待位置時一起調用。

常用方法清單

//構造函數,傳入線程數和等待完成後執行的動作
CyclicBarrier(int parties, Runnable barrierAction);
//構造函數,隻傳入線程數,等待完成無特定動作
CyclicBarrier(int parties);
//擷取執行個體化時傳入的線程數
int getParties();
//使目前線程在所有線程都運作到這裡之前一直等待,除非線程被中斷。
int await();
//使目前線程在所有線程都運作到這裡之前一直等待,除非線程被中斷或超出了指定的等待時間。
int await(long timeout, TimeUnit unit);
//查詢此屏障是否處于斷開狀态
boolean isBroken();
//将屏障重置為初始狀态
void reset();
//傳回目前在屏障處等待的線程數,此方法主要用于調試和斷言。
int getNumberWaiting();
           

應用示例

public class CyclicBarrierTest {

    private static CyclicBarrier cyclicBarrier;
    private static int NUM = 5;


    public static void main(String[] args) {

        //設定屏障的線程數量,和所有子線程都執行完一遍後要執行的代碼
        cyclicBarrier = new CyclicBarrier(NUM,()-> System.out.println("所有的子線程都運作到了屏障位置"));

        for (int i = 0; i < NUM; i++) {
            new Thread(new MyTask(),"子線程"+i).start();
        }

        System.out.println("主線程結束");

    }


    static class MyTask implements Runnable{

        @Override
        public void run() {
            for(int i=0;i<2;i++){
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName()+"開始執行");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(thread.getName()+"執行到屏障位置");
                try {
                    //每個子線程執行到這裡都會等待其他的子線程執行到這裡
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(thread.getName()+"執行結束");
            }
        }
    }
}
           

運作結果

子線程1開始執行
子線程2開始執行
子線程4開始執行
子線程3開始執行
主線程結束
子線程0開始執行
子線程2執行到屏障位置
子線程4執行到屏障位置
子線程3執行到屏障位置
子線程1執行到屏障位置
子線程0執行到屏障位置
所有的子線程都運作到了屏障位置
子線程0執行結束
子線程0開始執行
子線程2執行結束
子線程2開始執行
子線程4執行結束
子線程4開始執行
子線程1執行結束
子線程1開始執行
子線程3執行結束
子線程3開始執行
子線程1執行到屏障位置
子線程4執行到屏障位置
子線程2執行到屏障位置
子線程0執行到屏障位置
子線程3執行到屏障位置
所有的子線程都運作到了屏障位置
子線程3執行結束
子線程1執行結束
子線程4執行結束
子線程2執行結束
子線程0執行結束
           

繼續閱讀