Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Java to program CyclicBarrier with high concurrency

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "how to use Java high concurrency programming CyclicBarrier". Many people will encounter such a dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

What is CyclicBarrier?

What is CyclicBarrier? Take it apart and translate it into Cycle and Barrier.

Its main function is actually similar to CountDownLanch, is to let a group of threads reach a barrier to be blocked, until the last thread reaches the barrier, the barrier will be opened, all blocked threads will continue to execute, but it can be executed in a loop, which is the biggest difference with CountDownLanch. CountDownLanch is that other blocked threads will continue to execute only if the last thread sets the counter to 0.

How to use

First of all, let's take a look at a demo about using CyclicBarrier: for example, when there is a level in the game, you need to load some maps, special effects background music and so on every time you enter the next level. You can only play the game after it has been fully loaded:

/ * * demo Source https://blog.csdn.net/lstcui/article/details/107389371 * official account [java Finance] * / public class CyclicBarrierExample {static class PreTaskThread implements Runnable {private String task; private CyclicBarrier cyclicBarrier; public PreTaskThread (String task, CyclicBarrier cyclicBarrier) {this.task = task; this.cyclicBarrier = cyclicBarrier } @ Override public void run () {for (int I = 0; I)

< 4; i++) { Random random = new Random(); try { Thread.sleep(random.nextInt(1000)); System.out.println(String.format("关卡 %d 的任务 %s 完成", i, task)); cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } } public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () ->

{System.out.println ("all previous tasks at this level are completed, start the game.");}); new Thread (new PreTaskThread ("load Map data", cyclicBarrier). Start (); new Thread (new PreTaskThread ("load character Model", cyclicBarrier). Start () New Thread (new PreTaskThread ("load background Music", cyclicBarrier). Start ();}

The output is as follows:

We can see that every time the game starts, the game will not start until the character model, map data and background music of the game are loaded at the current level. And it can be cyclically controlled.

Source code analysis structure composition / * * The lock for guarding barrier entry * / private final ReentrantLock lock = new ReentrantLock (); / * * Condition to wait on until tripped * / private final Condition trip = lock.newCondition (); / * * The number of parties * / private final int parties; / * The command to run when tripped * / private final Runnable barrierCommand; / * * The current generation * / private Generation generation = new Generation ()

Lock: the lock used to protect the entrance to the barrier

Trip: threads that reach the barrier and cannot be released wait on the trip condition variable

Parties: the total number of arriving threads required to open the fence

BarrierCommand: the callback task executed after the last thread reaches the barrier

Generation: this is an inner class that enables CyclicBarrier reuse. Every time the await reaches the maximum number of times, it will re-new one, indicating that it has entered the next cycle. There is only one Boolean property, which is used to indicate whether there is a thread interrupt in the current cycle.

The main methods public int await () throws InterruptedException, BrokenBarrierException {try {return dowait (false, 0L);} catch (TimeoutException toe) {throw new Error (toe); / / cannot happen}} * Main barrier code, covering the various policies. * / private int dowait (boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException {final ReentrantLock lock = this.lock; lock.lock (); try {/ / gets the current generation of barrier, that is, the current cycle final Generation g = generation; if (g.broken) throw new BrokenBarrierException () If (Thread.interrupted ()) {breakBarrier (); throw new InterruptedException ();} / / each thread that calls the await method will subtract 1 int index =-- count; if (index = = 0) {/ / tripped boolean ranAction = false; try {final Runnable command = barrierCommand The barrierCommand passed in / / new CyclicBarrier, the command.run () method is synchronous. If it takes a lot of time, you need to consider whether to execute it asynchronously. If (command! = null) command.run (); ranAction = true; / / this method 1. Wake up all blocked threads, 2. Reset count (minus 1 for each thread that comes to count) and generation to facilitate the next loop. NextGeneration (); return 0;} finally {if (! ranAction) breakBarrier ();} / / loop until tripped, broken, interrupted, or timed out for ( ) {try {/ / enter the if condition, indicating that the await if (! timed) / / the current thread without timeout will release the lock, then enter the tail of the trip condition queue, and then suspend itself, waiting to be woken up. Trip.await (); else if (nanos > 0L) / / indicates that the current thread specified a timeout when calling the await method! Nanos = trip.awaitNanos (nanos);} catch (InterruptedException ie) {/ / Node node will throw an interrupt exception when it receives an interrupt signal when it is in the conditional queue! / / g = = generation is established, indicating that the current generation has not changed. / /! If the current generation of g.broken is not broken, the current thread breaks it and throws an exception.. 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. / / how many situations do I have when I execute to else? / / 1. The generation has changed, and there is no need to throw an interrupt exception at this time, because the generation has been updated, and the normal logic will follow after awakening here. Just set the interrupt flag. / / 2. The generation has not changed, but the generation has been broken, and there is no need to return an interrupt exception at this time. A brokenBarrier exception will be thrown when executed below. The interrupt flag bit is also recorded. After Thread.currentThread (). Interrupt ();}} / / wakes up and executes here, how many situations are there? / / 1. Normally, the current barrier has opened a new generation (trip.signalAll ()) / / 2. When the current Generation is broken, all threads / / 3 that are suspended on the trip will be awakened. The current thread trip waits for a timeout, then actively transfers to the blocking queue and then gets the lock wake-up. If (g.broken) throw new BrokenBarrierException (); / / after waking up, how many situations are there when it is executed here? / / 1. Normally, the current barrier has opened a new generation (trip.signalAll ()) / / 2. The current thread trip waits for a timeout, then actively transfers to the blocking queue and then gets the lock wake-up. After if (g! = generation) return index; / / wakes up and executes here, how many situations are there? / /. The current thread trip waits for a timeout, then actively transfers to the blocking queue and then gets the lock wake-up. If (timed & & nanos

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report