Java Realizes Limited Time CountDownLatch Parallel Scenario

  • 2021-10-15 10:40:22
  • OfStack

Directory business scenarios:
Solution:
Summarize

Business scenario:

One user data interface needs to return data within 20ms. Its calling logic is complex and there are many related interfaces. It needs to summarize data from three interfaces. The minimum time consumption of these summary interfaces also needs 16ms, and the optimal state time consumption of all summary interfaces needs 16ms*3=48ms

Solution:

Using parallel call interface, the result set is obtained simultaneously through multi-threads, and finally the results are integrated. In this scenario, the CountDownLatch of the concurrent package is used to complete the related operation. CountDownLatch is essentially a counter, which is initialized to the same number of tasks executed. When one task is executed, the value of the counter is subtracted by 1 until the calculator reaches 0, which means that all tasks have been completed. Wait for the thread on await and continue to execute.

For the tool class encapsulated for the above business scenario, two parameters are passed in: one parameter is the calculated number of task, and the other parameter is the milliseconds of the whole large task timeout.


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ParallelCollector {

    private Long timeout;
    private CountDownLatch countDownLatch;
    ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 1, TimeUnit.HOURS, new ArrayBlockingQueue<>(100));

    public ParallelCollector(int taskSize, Long timeOutMill) {
        countDownLatch = new CountDownLatch(taskSize);
        timeout = timeOutMill;
    }

    public void submitTask(Runnable runnable) {
        executor.execute(() -> {
            runnable.run();
            countDownLatch.countDown();
        });
    }

    public void await() {
        try {
            this.countDownLatch.await(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void destroy() {
        this.executor.shutdown();
    }
}

When the running time of a task exceeds the upper limit of the task time, it is stopped directly, which is the function of await ().

interface is a test class that simulates the timeout of remote service. After the program runs, it will output the execution results to map collection.


public class InterfaceMock {
    private  volatile  int num=1;

   public String slowMethod1() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return String.valueOf(num+1);
    };

   public String slowMethod2() {
        return String.valueOf(num+1);
    };

   public String slowMethod3() {
        return String.valueOf(num+1);
    };
}

Execute the get result test class in parallel


@SpringBootTest
class ThreadPoolApplicationTests {
    @Test
    void testTask() {
        InterfaceMock interfaceMock = new InterfaceMock();
        ParallelCollector collector = new ParallelCollector(3, 20L);
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        collector.submitTask(()->map.put("method1",interfaceMock.slowMethod1()));
        collector.submitTask(()->map.put("method2",interfaceMock.slowMethod2()));
        collector.submitTask(()->map.put("method3",interfaceMock.slowMethod3()));
        collector.await();
        System.out.println(map.toString());
        collector.destroy();
    }
}

When the execution time of method1 () is longer than 20ms, the method is terminated directly, and the result of map set does not have the result of method1 (). The result is as follows:

Summarize

In this way, the interface can return within a fixed time. Note that the number defined by CountDownLatch is the number of tasks, and using concurrentHashMap avoids the problem of confusion and wrong results during parallel execution.


Related articles: