Share a JDK batch asynchronous task tool CompletionService, super easy to use

Summary: CompletionService is recommended when you need to submit asynchronous tasks in batches. CompletionService integrates thread pool Executor and blocking queue to make batch asynchronous task management easier.

This article is shared from HUAWEI CLOUD Community " CompletionService, the Strongest Tool for JDK Batch Asynchronous Tasks ", author: JavaEdge.

How to optimize a code that queries various price interfaces? If "ThreadPoolExecutor+Future" is used, it may be optimized as follows:

The three threads execute the query price asynchronously, obtain the result by calling the get() method of Future three times, and then save the query result in MySQL.

If obtaining price1 takes a long time, even if obtaining price2 takes a short time, the operation of saving price2 cannot be executed first, because the main thread is blocked in f1.get(). How to solve this problem?

Add a blocking queue! Obtained prices 1, 2, and 3 all enter the blocking queue, and then consume the blocking queue in the main thread to ensure that the price obtained first is saved first:

CompletionService implements query price

The actual development recommends CompletionService, which can not only help you solve the price obtained first and save it first, but also simplify the code.

CompletionService maintains a blocking queue internally. When the task execution ends, the execution result of the task is queued. However, CompletionService queues the Future object of the task execution result, and the demo above queues the final execution result of the task.

Create CompletionService

The implementation class of the CompletionService interface is ExecutorCompletionService. There are two construction methods for this implementation class, namely:

  • ExecutorCompletionService(Executor executor);

  • ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue)

Both constructors need to pass in a thread pool. If completionQueue is not specified, the unbounded LinkedBlockingQueue is used by default. The Future object of the task execution result is added to the completionQueue.

Senior~ You can write a code to explain it to me directly~

Let's try to use CompletionService to implement a high-performance query price system. After that, submit three inquiry operations through CompletionService#submit(), and these three inquiry operations will be executed asynchronously by CompletionService.

Finally, CompletionService#take() obtains a Future object (the Future object of the task execution result added to the blocking queue), and calling Future#get() can return the execution result.

CompletionService interface

Methods provided by the CompletionService interface

There are two methods related to submit():

  • One method parameter is the Callable<V> task
  • A method has two parameters, namely Runnable task and V result, this method is similar to ThreadPoolExecutor's <T> Future<T> submit(Runnable task, T result) ,

CompletionService implements Dubbo#Forking Cluster

There is a cluster mode called Forking in Dubbo. In this cluster mode, multiple query services can be called in parallel. As long as one successfully returns the result, the entire service can be returned. For example, you need to provide an address-to-coordinate service. In order to ensure the high availability and performance of the service, you can call the APIs of three map service providers in parallel, and as long as one of them correctly returns the result r, the address-to-coordinate service will be You can directly return to r. This cluster mode can tolerate the exception of two map service providers, but the disadvantage is that it consumes too many resources.

 geocoder(addr) {
   // 并行执行以下3个查询服务, 
   r1=geocoderByS1(addr);
   r2=geocoderByS2(addr);
   r3=geocoderByS3(addr);
   // 只要r1,r2,r3有一个返回
   // 则返回
   return r1|r2|r3;
 }

The Forking cluster mode can be quickly implemented using CompletionService, such as the following sample code. First create a thread pool executor, a CompletionService object cs and a list futures of type Future<Integer>, each time an asynchronous task is submitted by calling the submit() method of CompletionService, a Future object will be returned, and these Future objects will be saved in the list in futures. By calling cs.take().get(), we can get the fastest returned task execution result. As long as we get a correctly returned result, we can cancel all tasks and return the final result.

 // 创建线程池
 ExecutorService executor =
   Executors.newFixedThreadPool(3);
 // 创建CompletionService
 CompletionService<Integer> cs =
   new ExecutorCompletionService<>(executor);
 // 用于保存Future对象
 List<Future<Integer>> futures =
   new ArrayList<>(3);
 // 提交异步任务,并保存future到futures 
 futures.add(
   cs.submit(()->geocoderByS1()));
 futures.add(
   cs.submit(()->geocoderByS2()));
 futures.add(
   cs.submit(()->geocoderByS3()));
 // 获取最快返回的任务执行结果
 Integer r = 0;
 try {
   // 只要有一个成功返回,则break
   for (int i = 0; i < 3; ++i) {
     r = cs.take().get();
     // 简单地通过判空来检查是否成功返回
     if (r != null) {
       break;
     }
   }
 } finally {
   // 取消所有任务
   for(Future<Integer> f : futures)
     f.cancel(true);
 }
 // 返回结果
 return r;

Summarize

When you need to submit asynchronous tasks in batches, CompletionService is recommended. CompletionService integrates thread pool Executor and blocking queue to make batch asynchronous task management easier.

CompletionService can make the execution results of asynchronous tasks orderly, and those that are executed first enter the blocking queue first. Using this feature, the orderliness of subsequent processing can be easily achieved, unnecessary waiting can be avoided, and requirements such as Forking Cluster can be quickly realized. .

The implementation class of CompletionService, ExecutorCompletionService, requires you to create a thread pool by yourself. Although it looks a bit long-winded, the advantage is that you can isolate the thread pools of multiple ExecutorCompletionServices. This isolation performance prevents several particularly time-consuming tasks from dragging down the entire application. risk.

 

Click Follow to learn about HUAWEI CLOUD's new technologies for the first time~

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4526289/blog/5520054