同步工具类-----循环栅栏:CyclicBarrier

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

public class TestCyclicBarrier {
    public static class Soldier implements Runnable {
        private String soldier;
        private final CyclicBarrier cyclicBarrier;
        private long timeout;

        public Soldier(CyclicBarrier cyclicBarrier, String soldier, long timeout) {
            this.cyclicBarrier = cyclicBarrier;
            this.timeout = timeout;
            this.soldier = soldier;
        }

        @Override
        public void run() {
            try {
                // 等待所有士兵到齐
                cyclicBarrier.await();
                doWork();
                // 等待所有士兵完成工作
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }

        }

        void doWork() {
            try {
                // Thread.sleep(Math.abs(new Random().nextInt() % 100000));
                Thread.sleep(timeout);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(soldier + ":任务完成!【用时: " + timeout / 1000 + " 秒】, " +
                    "当前线程:" + Thread.currentThread().getName());
        }
    }

    public static class BarrierRun implements Runnable {
        boolean flag;
        int N;

        private BarrierRun(boolean flag, int n) {
            this.flag = flag;
            N = n;
        }

        @Override
        public void run() {
            if (flag) {
                System.err.println("司令:【士兵" + N + "个,任务完成!】," +
                        "【当前执行线程:" + Thread.currentThread().getName() + "】");
            } else {
                System.err.println("司令:【士兵" + N + "个,集合完毕!】," +
                        "【当前执行线程:" + Thread.currentThread().getName() + "】");
                flag = true;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final int N = 10;
        Thread[] soldierThreads = new Thread[N];
        boolean flag = false;     // CyclicBarrier 可以接收一个Runnable类型参数作为barrierAction        // 所谓barrierAction就是当计数器一次计数完成(成功通过栅栏)后的栅栏操作,系统会在一个子任务线程中)执行的动作,但在阻塞线程被释放前是不能执行的;        // 如果所有线程都成功地通过了栅栏,那么await将为每个线程返回一个唯一的到达索引号,我们可以利用这些索引来“选举”产生一个领导线程,并在下一次迭代中由该领导线程执行一些特殊的工作。
        CyclicBarrier cyclicBarrier = new CyclicBarrier(N, new BarrierRun(flag, N));

        System.err.println("集合队伍!");

        TimeUnit.SECONDS.sleep(1);

        String tname;
        for (int i = 0; i < N; ++i) {
            System.out.println("士兵" + i + "报道!");
            long timeout = (int) (1 + Math.random() * 10) * 1000;
            tname = "士兵" + i;
            soldierThreads[i] = new Thread(new Soldier(cyclicBarrier, tname, timeout), tname);
            // soldierThreads[i].setName(tname);
            soldierThreads[i].start();
            /*if( i == 5){
                soldierThreads[i].interrupt();
            }*/
        }
    }
}

执行结果:

  1. 可见两次BarrierRun 任务分别是在 两个子任务线程中执行的。

原文地址:https://www.cnblogs.com/jvjs/p/10773570.html

时间: 2024-11-09 04:54:52

同步工具类-----循环栅栏:CyclicBarrier的相关文章

JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore

在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLatch 先看一下,CountDownLatch 源码的官方介绍. 意思是,它是一个同步辅助器,允许一个或多个线程一直等待,直到一组在其他线程执行的操作全部完成. public CountDownLatch(int count) { if (count < 0) throw new IllegalAr

同步工具类 CountDownLatch 和 CyclicBarrier

在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异步返回 Future ThreadLocal 类 线程池 ThreadPoolExecutor 同步工具类 CountDownLatch,CyclicBarrier,Semaphore,Phaser,Exchanger 估计上面每一个对于 2~3 年的 java 同学来说都是恶梦,比较难以理解,本文

java同步并发工具类CountDownLatch、CyclicBarrier和Semaphore

闭锁CountDownLatch 闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态.闭锁的作用相当于一扇门:在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过.当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态.闭锁可以用来确保某些活动直到其他活动都完成后才继续执行,例如: 确保某个计算在其需要的所有资源都被初始化之后才继续执行.二元闭锁(包括两个状态)可以用来表示"资源R已经被初始化",而

线程:CyclicBarrier同步工具类

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点.比如公司组织活动出去玩,需要在公司门口一起搭车去.每个人从家里出发去公司门口,到达的时间肯定先后不一样,所以公司的车要一直等待,等所有人到齐后,才开车出发.CyclicBarrier就类似这样的功能,当所有线程到达"屏蔽点"的时候,才往下走. 具体等待多少根线程到达,可以在构造方法里指定CyclicBarrier(int parties). 当你的parties设为3的时候,假设只有2根线程到达此处,那程序会一直在此等待.

Java并发(基础知识)——显示锁和同步工具类

显示锁                                                                                     Lock接口是Java 5.0新增的接口,该接口的定义如下: public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long

Java并发:线程间同步-条件队列和同步工具类

转载请注明出处: jiq?钦's technical Blog - 季义钦 线程之间的同步,除了互斥(前面介绍的互斥锁)之外,还存在协作关系,下面我们就介绍一下java线程间常见的一些协作方式. 一.内置条件队列 正如每个Java对象都可以作为一个内置锁,每个对象也可以作为一个条件队列,称为内置条件队列,Object.wait().notify()/notifyAll()构成了内置条件队列的API. 需要注意的是,调用任何对象X的内置条件队列的API都必须要先获得该对象X的内置锁. 1.API介

《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&amp;并发容器类&amp;同步工具类,消费者模式

上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Hashtable,此外还包括在JDK1.2中添加的一些功能相似的类,这些同步的封装器类由Collections.synchronizedXxx等工厂方法创建的.这些类实现线程安全的方式是:将他们的状态封装起来,并对每个共有方法都进行同步,使得每次只能有一个线程能访问容器的状态. 关于java中的Vect

Java 并发编程(四)常用同步工具类

同步工具类可以使任何一种对象,只要该对象可以根据自身的状态来协调控制线程的控制流.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括:信号量(Semaphore).栅栏(Barrier)以及闭锁(Latch). 闭锁 首先我们来介绍闭锁. 闭锁作用相当于一扇门:在闭锁到达某一状态之前,这扇门一直是关闭的,所有的线程都会在这扇门前等待(阻塞).只有门打开后,所有的线程才会同时继续运行. 闭锁可以用来确保某些活动直到其它活动都完成后才继续执行,例如: 1.确保某个计算在其所有资源都被初始化之后才

【JAVA并发】同步工具类

同步工具类主要包括闭锁(如CountDownLatch),栅栏(如CyclicBarrier),信号量(如Semaphore)和阻塞队列(如LinkedBlockingQueue)等: 使用同步工具类可以协调线程的控制流: 同步工具类封装了一些状态,这些状态决定线程是继续执行还是等待,此外同步工具类还提供了修改状态的方法: 下面将简单介绍以上同步工具类: 闭锁 可以让一个线程等待一组事件发生后(不一定要线程结束)继续执行: 以CountDownLatch为例,内部包含一个计数器,一开始初始化为一