Java中CyclicBarrier的简单使用及原理

1.类说明

    等待一组进程,共同达到一个障碍点或是将在给定数量的参与者(线程)处于等待状态时启动。

    CyclicBarrie支持一个可选的Runnable。在一组进程达到障碍点后执行。

    构造方法:

        CyclicBarrier(int parties)   
        CyclicBarrier(int parties, Runnable barrierAction)  

 

2.简单例子

package com.mt.demo;

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

public class MyCyclicBarrier {

    private final static int THREAD_NUM = 5;


    //线程
    static class Worker implements Runnable {

        CyclicBarrier cb = null;

        public Worker(CyclicBarrier cb) {
            this.cb = cb;
        }

        @Override
        public void run() {
            try {
                System.out.println("worker waiting");
                cb.await();
                System.out.println(Thread.currentThread().getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //Runnable可选
        CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
            @Override
            public void run() {
                System.out.println("construct Runnbale");
            }
        });

        for (int i = 0; i < THREAD_NUM; i++) {
            new Thread(new Worker(cb)).start();
        }
    }
}

输出:

worker waiting
worker waiting
worker waiting
worker waiting
worker waiting
construct Runnbale
15
11
13
12
14

 

3.实现原理

    await等待所有的parties被调用。实际执行dowait

    /**
     * Waits until all {@linkplain #getParties parties} have invoked
     * {@code await} on this barrier.
     */
    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe); // cannot happen
        }
    }
 // loop until tripped, broken, interrupted, or timed out
            for (;;) {
                try {
                    if (!timed)
                        //重要,trip条件阻塞,此时lock锁释放
                        trip.await();
                    else if (nanos > 0L)
                        nanos = trip.awaitNanos(nanos);
                } catch (InterruptedException ie) {
                    if (g == generation && ! g.broken) {
                        breakBarrier();
                        throw ie;
                    } else {
                        // We're about to finish waiting even if we had not
                        // been interrupted, so this interrupt is deemed to
                        // "belong" to subsequent execution.
                        Thread.currentThread().interrupt();
                    }
                }

                if (g.broken)
                    throw new BrokenBarrierException();

                if (g != generation)
                    return index;

                if (timed && nanos <= 0L) {
                    breakBarrier();
                    throw new TimeoutException();
                }
            }

 

上面还有几行代码没贴,如果可以Lock,count--,判断count是否为0,不是0进入for循环。可以重新lock;是0说明可以执行断点,判断commend是否为null,不是执行Rannable。之后调用nextGeneration,进入下个周期。

 

转载于:https://my.oschina.net/xiaopei/blog/861731

评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页