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****