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

Case Analysis of Loop Barrier CyclicBarrier in Java concurrent programming

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article Xiaobian introduces in detail for you "Java concurrent programming loopback barrier CyclicBarrier case analysis", the content is detailed, the steps are clear, and the details are handled properly. I hope this "Java concurrent programming loopback barrier CyclicBarrier case analysis" article can help you solve your doubts.

CyclicBarrier

The CountDownLatch described earlier has many optimizations compared to the join method of the calling thread in solving the synchronization of multiple threads. But the counter of CountDownLatch is one-time, that is, after the counter value is 0, calling the await and countdown methods of CountDownLatch will return immediately, which will not have the effect of thread synchronization. So in order to meet the need for counters to be reset, the JDK development team provides the CyclicBarrier class, and the functionality of the CyclicBarrier class is not limited to the functionality of CountDownLatch. CyclicBarrier literally means loopback barrier, which allows a group of threads to reach a state and then all execute at the same time. This is called a loopback because it can be reused when all waiting threads finish executing and reset the state of the CyclicBarrier. It is called a barrier because the thread is blocked after calling the await method, and this blocking point is called the barrier point, and after all threads have called the await method, the threads break through the barrier and continue to run down. Before introducing the principle, several examples are introduced in order to deepen the understanding. In the following example, what we want to achieve is to use two threads to execute a decomposed task A, and then summarize the results of the two threads after they have finished executing their own tasks.

Import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CycleBarrierTest {/ / create a thread pool with a fixed number of threads private static CyclicBarrier cyclicBarrier = new CyclicBarrier (2, new Runnable () {@ Override public void run () {System.out.println (Thread.currentThread () + "task1 merge result");}}) Public static void main (String [] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool (2); / / add thread A to the thread pool executorService.submit (new Runnable () {@ Override public void run () {try {System.out.println (Thread.currentThread () + "task1")) System.out.println (Thread.currentThread () + "enter in barrier"); cyclicBarrier.await (); System.out.println (Thread.currentThread () + "enter out barrier");} catch (Exception e) {e.printStackTrace ();}) / / add thread B to the thread pool executorService.submit (new Runnable () {@ Override public void run () {try {System.out.println (Thread.currentThread () + "task2"); System.out.println (Thread.currentThread () + "enter in barrier"); cyclicBarrier.await () System.out.println (Thread.currentThread () + "enter out barrier");} catch (Exception e) {e.printStackTrace ();}); / / close thread pool executorService.shutdown ();}}

The code above creates a CyclicBarrier object whose first parameter is the initial value of the counter, and the second number Runable is the task that needs to be performed when the count value is 0. A thread pool of size 2 is first created in the main function. Then add two subtasks to the thread pool, each of which invokes the method after executing its own logic. The initial counter value is 2, and when the first thread calls the await method, the counter value is decremented to 1. Because the counter value is not 0, the current thread reaches the barrier point and is blocked. Then when the second thread calls await, it enters the barrier, and the counter value is decremented. Now that the counter value is 0, it executes the task in the CyclicBarrier constructor, exits the barrier point after execution, and wakes up the blocked second thread. At this point, the first thread will also exit the barrier and continue to run down.

The above example shows that multiple threads are waiting for each other. If the counter value is N, then the N1 thread that then calls the await method will be blocked because it reaches the barrier point. When the Nth thread calls await, the counter value is 0, and then the Nth thread will issue a notice to wake up the previous N1 thread. That is, when all threads reach the barrier point, they can continue to execute downward together. For this example, you can get a similar output using CountDownLatch. Here is another example to illustrate the reusability of CyclicBarrier.

Suppose a task consists of phase 1, phase 2, and phase 3, and each thread executes phase 1, 2, and 3 sequentially. When multiple threads execute the task, it is necessary to ensure that all threads' phase 1 is completed before entering phase 2 execution, and when all threads' phase 2 is completed before entering phase 3 execution. Let's use CyclicBarrier to accomplish this requirement.

Import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CycleBarrierTest1 {/ / create a thread pool with a fixed number of threads private static CyclicBarrier cyclicBarrier = new CyclicBarrier (2); public static void main (String [] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool (2) / / add thread A to thread pool executorService.submit (new Runnable () {@ Override public void run () {try {System.out.println (Thread.currentThread () + "step1"); cyclicBarrier.await (); System.out.println (Thread.currentThread () + "step2")) CyclicBarrier.await (); System.out.println (Thread.currentThread () + "step3"); cyclicBarrier.await ();} catch (Exception e) {e.printStackTrace ();}) / / add thread B to thread pool executorService.submit (new Runnable () {@ Override public void run () {try {System.out.println (Thread.currentThread () + "step1"); cyclicBarrier.await (); System.out.println (Thread.currentThread () + "step2")) CyclicBarrier.await (); System.out.println (Thread.currentThread () + "step3"); cyclicBarrier.await ();} catch (Exception e) {e.printStackTrace ();}) / / close thread pool executorService.shutdown ();}}

In the above code, each child thread calls the await method after executing phase 1, and all threads will not go down until all threads have reached the barrier point, which ensures that all threads have completed phase 1 before they begin to execute phase 2.

After reading this, the article "CyclicBarrier instance Analysis of Java concurrent programming Loop Barrier" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it yourself. If you want to know more about related articles, welcome to follow the industry information channel.

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