CyclicBarrier用法

前面介绍了CountDownLatch,可以实现计数。达到指定的数后,就会同时执行。
那么CyclicBarrier跟CountDownLatch实现的功能差不多。

import java.util.Random;
import java.util.concurrent.*;

/**
 * await()就好比是屏障,经过指定数量的屏障才可以执行最后的线程。
 * 或者说是一直等待,直到await()的数量是指定的数量后才会执行下面的
 */
public class CyclicbarrierTest {

    private static final int THREAD_NUM = 3;

    public static void main(String[] args) {
        CyclicbarrierTest t = new CyclicbarrierTest();
        t.tttt();
    }

    public void tttt(){
        CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
            public void run() {
                System.out.println("都准备好了");
                try {
                    Thread.sleep(2000);
                    return;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_NUM,THREAD_NUM,0, TimeUnit.SECONDS,new LinkedBlockingQueue());
        for (int i = 1; i <= THREAD_NUM; i++) {
            Task t = new Task(""+i,cb);
            executor.execute(t);
        }

        System.out.println("我的任务已经分派完毕...");
    }

    class Task implements Runnable{
        private CyclicBarrier cb;
        private String taskName;
        public Task(){

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

        public void run() {
            try {
                Random r = new Random();
                int slt = r.nextInt(10);
                Thread.sleep(slt*1000);
                System.out.println(taskName+"使用了"+slt+"秒,准备好了");
                cb.await();
                System.out.println(taskName+"继续执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

执行结果:

我的任务已经分派完毕...
1使用了3秒,准备好了
3使用了4秒,准备好了
2使用了9秒,准备好了
都准备好了
2继续执行
1继续执行
3继续执行

await()方法在等待所有的线程都通过了屏障,就会执行CyclicBarrier内部的线程,执行完内部线程后,子线程会继续执行。
同时我们看到看到CyclicBarrier会阻塞子线程,不会阻塞主线程。

可以看到是分两步的:
第一步:所有的线程都会阻塞,然后执行CyclicBarrier内部线程;
第二部:CyclicBarrier内部线程执行完后,各子线程又开始继续运行。

同时在CyclicBarrier内部线程中还可以继续调用CyclicBarrier。

public static void main(String[] args) {
        CyclicbarrierTest t = new CyclicbarrierTest();
        t.tttt();
    }

    public void tttt(){
        CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
            public void run() {
                System.out.println("都准备好了");
                try {
                    Thread.sleep(2000);
                    System.out.println("调用下一层");

                    //在CyclicBarrier调用下一层CyclicBarrier
                    tt();

                    return;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_NUM,THREAD_NUM,0, TimeUnit.SECONDS,new LinkedBlockingQueue());
        for (int i = 1; i <= THREAD_NUM; i++) {
            Task t = new Task(""+i,cb);
            executor.execute(t);
        }

        System.out.println("我的任务已经分派完毕...");
    }

    public void tt(){
        CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
            public void run() {
                System.out.println("我是另一个CyclicBarrier");
                try {
                    Thread.sleep(2000);
                    return;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_NUM,THREAD_NUM,0, TimeUnit.SECONDS,new LinkedBlockingQueue());
        for (int i = 1; i <= THREAD_NUM; i++) {
            Task t = new Task("=>"+i,cb);
            executor.execute(t);
        }
    }

执行结果:

我的任务已经分派完毕...
1使用了5秒,准备好了
3使用了9秒,准备好了
2使用了9秒,准备好了
都准备好了
调用下一层
2继续执行
1继续执行
3继续执行
=>3使用了7秒,准备好了
=>1使用了7秒,准备好了
=>2使用了8秒,准备好了
我是另一个CyclicBarrier
=>2继续执行
=>3继续执行
=>1继续执行
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值