CyclicBarrier:循環柵欄

CyclicBarrier是另一種多線程併發的是工具,和CountDownLatch非常類似,它也可以實現線程間的計數等待,它的功能比CountDownLatch更加強大。因爲CyclicBarrier是循環柵欄,所有的線程必須在柵欄處等待,並且可以循環使用。假設我們將計數器設置爲10,那麼湊齊第一個10個線程後,計數其就會歸0,並重新計算。

比如我們要求十個線程一起去執行任務;這時我們需要先讓這10個線程集合,接着,一起去執行任務,當這10個線程吧任務都執行完了,那麼纔算任務全部執行完畢!

CycliBarrier比CountDownLatch稍微強大點,CycliBarrier可以接收一個參數作爲barrierAction,所謂barrierAction就是當計數器一次計數完成後,系統會執行的動作,如下構造函數中,parties表示計數總數,也就是參與的線程總數。

public CyclicBarrier(int perties, Runnable barrierAction);

示例代碼如下所示:

package cn.yan.current;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class TestCyclicBarrier {

    public static class Task implements Runnable {
        private String taskName;
        private final CyclicBarrier cyclicBarrier;

        public Task(String taskName, CyclicBarrier cyclicBarrier) {
            this.taskName = taskName;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                // 等待所有任務到齊
                cyclicBarrier.await();
                doTask();
                // 等待所有任務執行完畢
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException ex) {
                ex.printStackTrace();
            }
        }

        void doTask() {
            try {
                Thread.sleep(Math.abs(new Random().nextInt() % 10000));
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println("task over!");
        }
    }

    public static class BarrierAction implements Runnable {
        private boolean flag;
        private int n;

        public BarrierAction(boolean flag, int n) {
            this.flag = flag;
            this.n = n;
        }

        @Override
        public void run() {
            if (flag) {
                System.out.println("第" + n + "個,任務完成!");
            } else {
                System.out.println("task" + n + "個,集合完畢!");
                flag = true;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final int n = 10;
        Thread[] allTasks = new Thread[10];
        boolean flag = false;

        CyclicBarrier cyclicBarrier = new CyclicBarrier(n, new BarrierAction(flag, n));
        // 設置屏障點
        System.out.println("任務集合");
        for (int i = 0; i < n; i++) {
            System.out.println("第" + i + "任務準備執行。");
            allTasks[i] = new Thread(new Task("任務" + i, cyclicBarrier));
            allTasks[i].start();
        }
    }
}

其執行結果如下:

/usr/jdk-9.0.1/bin/java -javaagent:/home/shuai/software/idea-IU-173.3727.127/lib/idea_rt.jar=42317:/home/shuai/software/idea-IU-173.3727.127/bin -Dfile.encoding=UTF-8 -classpath /home/shuai/IdeaProjects/cn-netty/out/production/classes cn.yan.current.TestCyclicBarrier
任務集合
第0任務準備執行。
第1任務準備執行。
第2任務準備執行。
第3任務準備執行。
第4任務準備執行。
第5任務準備執行。
第6任務準備執行。
第7任務準備執行。
第8任務準備執行。
第9任務準備執行。
task10個,集合完畢!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
第10個,任務完成!

Process finished with exit code 0

 

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