Completion Service performs asynchronous tasks in batches

Posted by Valect on Wed, 25 Sep 2019 05:22:28 +0200

Completion Service also maintains a blocking queue internally. When the task is finished, it adds the result of the task to the blocking queue. The difference is that Completion Service adds the Future object of the result of the task to the blocking queue.

What can Completion Service do?

The results of the asynchronous task are saved in the queue, and the main thread takes the result data from the queue for execution.

Scenario: Inquire from different e-commerce platforms and save prices

Using the "ThreadPool Executor + Future" scheme: Asynchronous execution of inquiries and then save

//	Create thread pools 
ExecutorService	executor = Executors.newFixedThreadPool(3); 
//	Asynchronous Inquiry to E-Commerce S1 
Future<Integer>	f1 = executor.submit(()->getPriceByS1()); 
//	Asynchronous Inquiry to E-commerce S2 
Future<Integer>	f2=	executor.submit(()->getPriceByS2()); 			
//	Obtain E-commerce S1 quotation and save it asynchronously 
executor.execute(()->save(f1.get()));		
//	Get E-commerce S2 Quotation and Asynchronous Preservation 
executor.execute(()->save(f2.get())		

If it takes a long time to get the E-commerce S1 quotation, then even if the E-commerce S2 quotation takes a short time, the operation of saving the S-2 quotation can not be executed first, because the main thread is blocked in the f1.get() operation. How do you deal with this minor flaw?

Add a blocking queue, get the S1, S2 quotations into the blocking queue, and then consume the blocking queue in the main thread, so as to ensure that the first quotations are saved to the database. Completion Service in the Java concurrent toolkit can implement this solution.

Create Completion Service

ExecutorCompletionService is an implementation class of the CompletionService interface. This implementation class is constructed in two ways:

//First, by default, unbounded Linked Blocking Queue is used
ExecutorCompletionService (Executor	executor)
//Second, you can customize the queue    
ExecutorCompletionService (Executor	executor,BlockingQueue<Future<V>> completionQueue)

Example:

//	Create thread pools 
ExecutorService	executor =	Executors.newFixedThreadPool(10); 
//	Create Completion Service 
CompletionService<Integer> cs =	new	ExecutorCompletionService<>(executor); 
//	Asynchronous Inquiry to E-Commerce S1 
cs.submit(()->getPriceByS1()); 
//	Asynchronous Inquiry to E-commerce S2 
cs.submit(()->getPriceByS2()); 
//	Asynchronous Inquiry to E-Commerce S3 
cs.submit(()->getPriceByS3()); 
//	Save the inquiry results asynchronously to the database 
for	(int i=0; i<3;i++)	{		
    Integer r =	cs.take().get();
    executor.execute(()->save(r)); 
}

CompletionService API

Submitting relevant api

//	Submitting Callable Tasks
Future<V> submit(Callable<V> task); 
//	Submit Runnable Tasks and Result Quotations
Future<V> submit(Runnable task, V result); 

Blocking-related api

//Get and remove an element from the blocking queue. If the blocking queue is empty, the thread calling the take() method will be blocked.
Future<V>	take() throws InterruptedException; 
//Gets and removes an element from the blocking queue, returns null if the blocking queue is empty
Future<V>	poll(); 
/**
 *Get and remove an element from the blocking queue. If the blocking queue is empty waiting for timeout unit time, the blocking queue is empty.
 *This method returns the null value.
 */
Future<V>	poll(long timeout, TimeUnit	unit) throws InterruptedException;

summary

  • Completion Service is recommended when batch submission of asynchronous tasks is required.
  • Completion Service integrates the functions of thread pool Executor and blocking queue BlockingQueue to make batch asynchronous task management easier.
  • Completion Service enables the execution of asynchronous tasks to be ordered, first completed into the blocking queue. With this feature, you can easily achieve the orderliness of subsequent processing, avoid unnecessary waiting, and quickly implement requirements such as Forking Cluster.
  • ExecutorCompletion Service, an implementation class of Completion Service, requires you to create thread pools yourself. Although it may seem verbose, the advantage is that you can isolate multiple ExecutorCompletion Service thread pools, which avoids the risk that several particularly time-consuming tasks will drag down the entire application.

****** Code words are not easy. If they are helpful to you, please pay attention to them.

******** Love Technology Love Life QQ Group: 894109590****

Topics: Programming Database Java