Effect
When a group of threads reaches a barrier (or synchronization point), they are blocked. The barrier will not open until the last thread reaches the barrier, and all threads blocked by the barrier will continue to run.
Core method
- Cyclic Barrier (int parties): The default constructor, the parties parameter represents the number of threads blocked by the barrier
- Cyclic Barrier (int parties, Runnable Barrier Action): Barrier Action indicates that when the barrier is open, the barrier Action thread will be executed first, and the barrier action will be executed directly with the thread that reaches the barrier last.
- await(): Tell Cyclic Barrier that I have reached the barrier, and then the current thread is blocked until all threads reach the barrier, and the barrier opens and executes together.
- reset(): reset counter
- The getNumberWaiting method can obtain the number of threads blocked by Cyclic-Barrier
- The isBroken() method is used to know if a blocked thread has been interrupted
Application scenario
Cyclic Barrier can be used to compute data in multi-threads and finally merge the scenarios of computed results.
Example
package com.xiaolyuh; import com.alibaba.fastjson.JSON; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CyclicBarrier; /** * CyclicBarrier Concurrent Tool Class * * @author yuhao.wang3 * @since 2019/6/27 15:52 */ public class CyclicBarrierTest { public static void main(String[] args) { Random random = new Random(); Map<String, Long> map = new ConcurrentHashMap<>(); CyclicBarrier cyclicBarrier = new CyclicBarrier(4, () -> { System.out.println(Thread.currentThread().getName() + " 3 When all threads reach the barrier, they execute first barrierAction Threads..."); System.out.println(Thread.currentThread().getName() + " 3" + JSON.toJSONString(map)); }); for (int i = 0; i < 3; i++) { new Thread(() -> { try { Thread.sleep(200 + random.nextInt(200)); System.out.println(Thread.currentThread().getName() + " 1 Waiting for all threads to reach the barrier------------"); map.put(Thread.currentThread().getName(), Thread.currentThread().getId()); cyclicBarrier.await(); System.out.println(Thread.currentThread().getName() + " 2 When all threads reach the barrier, they start executing business code================"); } catch (Exception e) { e.printStackTrace(); } }).start(); } try { cyclicBarrier.await(); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + " Main thread completion"); } catch (Exception e) { e.printStackTrace(); } } }
Output results:
Thread-1 1 Waiting for all threads to reach the barrier------------ Thread-0 1 Waiting for all threads to reach the barrier------------ Thread-2 1 Waiting for all threads to reach the barrier------------ Thread-2 3 When all threads reach the barrier, they execute first barrierAction Threads... Thread-2 3{"Thread-0":13,"Thread-1":14,"Thread-2":15} Thread-2 2 When all threads reach the barrier, they start executing business code================ Thread-1 2 When all threads reach the barrier, they start executing business code================ Thread-0 2 When all threads reach the barrier, they start executing business code================ main Main thread completion
Reference resources
Art of concurrent programming in java
Source code
https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases
spring-boot-student-concurrent project
layering-cache
Laying-cache, a multi-level caching framework for monitoring This is an implementation of my open source multi-level caching framework. If you are interested, take a look at it.