AQS—CyclicBarrier

简单介绍

        CyclicBarrier也是一个同步辅助类,它允许一组线程相互等待,直到到达某个公共的屏障点,只有当每个线程都准备就绪后,才能各自继续往下执行后续的操作。它和CountDownLatch有些相似的地方,都是通过计数器来实现的,当某个线程调用了await()方法之后呢,该线程就进入等待状态,而且计数器执行的是+1操作,当计数器的值达到我们设置的初始值的时候,因为调用await()方法进入等待状态的线程会被唤醒,继续执行它们后续的操作。由于CyclicBarrier在释放等待线程后可以重用,所以称它为循环屏障,可以循环使用。

应用场景

        CyclicBarrier的使用场景和CountDownLatch很相似,它可以用于多线程计算数据最后合并计算结果的应用场景。

与CountDownLatch的区别

        1、CountDownLatch的计数器只能使用一次;而CyclicBarrier的计数器可以使用reset()方法重置,循环使用。

        2、CountDownLatch主要是实现1个或n个线程需要等待其它线程完成某项操作之后才能继续往下执行,它描述的是1个或n个线程等待其它线程的关系;而CyclicBarrier主要是实现了多个线程之间相互等待,直到所有线程都满足了条件之后才能继续执行后续的操作,它描述的是各个线程内部相互等待的关系。

使用举例

package com.yuxing.springbootdemo.juc;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CyclicBarrierExample1 {
	
	private static CyclicBarrier barrier = new CyclicBarrier(5);
	
	public static void main(String[] args) throws InterruptedException {
		ExecutorService executor = Executors.newCachedThreadPool();
		for(int i=0;i<10;i++) {
			final int threadNum = i;
			Thread.sleep(1000);
			executor.execute(() -> {
				try {
					race(threadNum);
				} catch (Exception e) {
					log.error("exception", e);
				} 
			});
		}
		executor.shutdown();
	}
	
	private static void race(int threadNum) throws InterruptedException, BrokenBarrierException {
		Thread.sleep(1000);
		log.info("{} is ready", threadNum);
		barrier.await();
		log.info("{} continue", threadNum);
	}
	
}

运行结果:

12:36:08.804 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 0 is ready
12:36:09.802 [pool-1-thread-2] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 1 is ready
12:36:10.803 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 2 is ready
12:36:11.803 [pool-1-thread-4] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 3 is ready
12:36:12.804 [pool-1-thread-5] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 4 is ready
12:36:12.804 [pool-1-thread-2] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 1 continue
12:36:12.804 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 2 continue
12:36:12.804 [pool-1-thread-4] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 3 continue
12:36:12.804 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 0 continue
12:36:12.804 [pool-1-thread-5] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 4 continue
12:36:13.804 [pool-1-thread-6] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 5 is ready
12:36:14.804 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 6 is ready
12:36:15.805 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 7 is ready
12:36:16.805 [pool-1-thread-4] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 8 is ready
12:36:17.806 [pool-1-thread-5] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 9 is ready
12:36:17.806 [pool-1-thread-3] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 6 continue
12:36:17.806 [pool-1-thread-6] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 5 continue
12:36:17.806 [pool-1-thread-4] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 8 continue
12:36:17.806 [pool-1-thread-1] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 7 continue
12:36:17.806 [pool-1-thread-5] INFO com.yuxing.springbootdemo.juc.CyclicBarrierExample1 - 9 continue

猜你喜欢

转载自blog.csdn.net/N2H4N2H4/article/details/82915701
AQS