Surprise concurrent programming JUC series demo code address: github.com/mtcarpenter…

Hello, everyone, we meet again, assault concurrent programming JUC series actual combat concurrent tools off. The new chapter or the new story explanation, I don’t know everyone in the interview encountered CountDownLatch, CyclicBarrier, Semaphore and recovery tool soul. This section provides CountDownLatch, a means of concurrent process control.

Basic introduction

CountDownLatch allows one or more threads to wait for other threads to complete an operation. In daily development, it is common to encounter scenarios in which multiple threads need to be opened in the main thread to execute tasks in parallel, and the main thread needs to wait for all child threads to complete execution before summarizing. Before CountDownLatch, threads’ join() methods were commonly used to do this, but the Join () method was not flexible enough to meet the needs of different scenarios. A series of concurrent flow control classes are used in the JDK to make the code more elegant. Waiting for a sequence of operations to complete using a JOIN might look like this:

// A thread waits
thread.join();
// Multiple threads are waiting
for (Thread thread : list) {
      thread.join();
} Copy the code

CountdownLatch running flowchart

image.png

For example, if the initial value of CountDownLatch is 3, the thread will call await. The current number of threads greater than 0 will block and wait. Each time T1, T2, and T3 call the countDown method, the count will decrease by 1. The blocking thread TA is released to perform the remaining operations.

Listen to stories and learn techniques

The annual Arbor Day, the arrival of the new day primary school in response to the call of national tree planting and greening, held everyone to participate in the “protect the city small guard tree planting activities”, god animals came to the classroom early, after the departure of each teacher in the classroom to explain the safety knowledge related to tree planting, and the purpose of the activity. All the gods waited for the bell to ring, and the gods gathered in the playground in unison, as follows:

public class CountDownLatchExample1 {

    private final static int gradeNum = 6;

    public static void main(String[] args) throws Exception {
 ExecutorService exec = Executors.newScheduledThreadPool(gradeNum);  // Ring signal  final CountDownLatch countDownLatch = new CountDownLatch(1);  for (int i = 0; i < gradeNum; i++) {  int gradeName = i + 1;  exec.submit(() -> {  try {  countDownLatch.await();  wait(gradeName);   } catch (Exception e) {  }  });  }  // Enable notifications after 3 seconds  TimeUnit.SECONDS.sleep(3);  System.out.println("Notice, notice, please all students to the playground quickly gather.....");  countDownLatch.countDown();   exec.shutdown();  }   private static void wait(int gradeName) throws Exception {  TimeUnit.MILLISECONDS.sleep((int) Math.random() * 1000);  System.out.println(gradeName + "All grade students arrive at the playground.");  } }  Copy the code

Countdownlatch.countdown (); countDownLatch = 0; countDownLatch = 0; countDownLatch = 0 All countdownlatch.await () signals that are 0 are unblocked and continue with the next task. The running results are as follows:

Notice, notice, please all students to the playground quickly gather.....4All grade students arrive at the playground1All grade students arrive at the playground6All grade students arrive at the playground2All grade students arrive at the playground3All grade students arrive at the playground5All grade students arrive at the playgroundCopy the code

The main thread waits for the child thread to complete

The leader said that this activity would be organized by grade on the playground. The number of students in each grade was not the same, and the sorting time was not the same. Each class report would be sent to the leader, who would wait for all six grades to be sorted out and open the school gate to set out. An example of how to implement CountDownLatch is as follows:

public class CountDownLatchExample2 {
    private final static int gradeNum = 6;
    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newScheduledThreadPool(gradeNum);
        final CountDownLatch countDownLatch = new CountDownLatch(gradeNum);
 for (int i = 0; i < gradeNum; i++) {  int gradeName = i + 1;  exec.submit(() -> {  try {  wait(gradeName);  } catch (Exception e) {  } finally {  countDownLatch.countDown();  }  });  }  System.out.println("Waiting for all grades to assemble and prepare.....");  countDownLatch.await();  System.out.println("All grades ready, go.........");  exec.shutdown();  }  private static void wait(int gradeName) throws Exception {  TimeUnit.MILLISECONDS.sleep((int) Math.random() * 1000);  System.out.println(gradeName + "The grade is ready.");  } } Copy the code

We create six thread pools with newScheduledThreadPool(gradeNum). Each pool represents a class. CountDownLatch(gradeNum) represents the number of classes we need to count. TimeUnit.MILLISECONDS.sleep((int) Math.random() * 1000); Random time, used to represent the finishing time of each class. The main thread is blocked after calling the countdownlatch.await () method. The countdownlatch.countdown () method is called to decrease the counter inside countDownLatch by one after the child thread has finished executing. After all the child threads have finished executing and called countDown (), the counter becomes zero and the await () method of the main thread returns. The running code is as follows:

Wait for all grades to assemble and prepare.....2The grade is ready5The grade is ready3The grade is ready6The grade is ready1The grade is ready4The grade is readyAll grades ready, go.........Copy the code

The main thread waits for the child thread to complete

The leadership of the school set out at 8 o ‘clock, of course, just go to the first grade children, must not be so fast as big brother finishing, resulting in other grades are gone, the first grade to prepare the scene, the code implementation is as follows:

public class CountDownLatchExample3 {
    private final static int gradeNum = 6;
    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newScheduledThreadPool(gradeNum);
        final CountDownLatch countDownLatch = new CountDownLatch(gradeNum);
 for (int i = 0; i < gradeNum; i++) {  int gradeName = i + 1;  exec.submit(() -> {  try {  wait(gradeName);  } catch (Exception e) {  } finally {  countDownLatch.countDown();  }  });  }  System.out.println("Waiting for all grades to assemble and prepare.....");  countDownLatch.await(1000, TimeUnit.MILLISECONDS);  System.out.println("8 o 'clock ready grade, go first.........");  exec.shutdown();  }  private static void wait(int gradeName) throws Exception {  // The wait time is longer for the first grade  if (gradeName == 1) {  TimeUnit.SECONDS.sleep(2);  } else {  TimeUnit.MILLISECONDS.sleep((int) Math.random() * 1000);  }  System.out.println(gradeName + "The grade is ready.");  } } Copy the code

This code has an extra countdownlatch.await (1000, timeunit.milliseconds) compared to the previous code; The await of countDownLatch can wait for the timeout period, and the main latch will not be blocked whether or not the business completes within the specified time. The running results are as follows:

Wait for all grades to assemble and prepare.....3The grade is ready4The grade is ready2The grade is ready6The grade is ready5The grade is ready8Point ready grade, start.........1The grade is readyCopy the code

Welcome to the public accountThe mountain carpenter,I am Xiao Chun brother, engaged in Java back-end development, will be a little front-end, through the continuous output of a series of technical articles to meet friends, if this article can help you, welcome to pay attention to,Looking at,Like, share support,See you next time!