Java concurrency topic with return results for batch task run Completionservice Executorservice.invokeall

Source: Internet
Author: User

Reprint please indicate source: http://blog.csdn.net/lmj623565791/article/details/27250059

Under normal circumstances, we use runnable as the main task representation, but Runnable is a very limited abstraction, the Run method can only log, print, or aggregate data into a container (on the one hand memory consumption is large, there is a need to control synchronization, Very high efficiency limit), in short, can not return the results of the operation, for example, 1000 tasks to crawl the data on the network at the same time, and then the captured data processing (variable processing), I think the best way is to provide a callback interface, the process of the most callback passed in But now we have a better way to achieve: Completionservice + callable

The call method of callable can return the result of running;

Completionservice the executor (thread pool) and Blockingqueue (block queue) together, using callable as the basic unit of the task at the same time, the whole process is that the producer keeps putting the callable task into a blockage, Executor as a consumer constantly pull the task out to run, and return the results;

Advantage:

A, blocking the queue to prevent the memory queue to wait for too many tasks, causing memory overflow (after all, the general producer speed is faster, such as the crawler prepared URLs and rules, to run, run up (consumer) or slower)

B, Completionservice can achieve, which task first run completed return, rather than in order to return, this can greatly improve efficiency;

1, Completionservice:executor + blockingqueue

Here's a sample example:

Package Com.zhy.concurrency.completionservice;import Java.util.random;import Java.util.concurrent.BlockingQueue; Import Java.util.concurrent.callable;import Java.util.concurrent.completionservice;import Java.util.concurrent.executionexception;import Java.util.concurrent.executorcompletionservice;import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import java.util.concurrent.Future; Import java.util.concurrent.linkedblockingdeque;/** * Combines executor and BLOCKINGQUEUE functions to deliver the callable task to it to run, Then use the take () method to get the finished result * * @author Zhy * */public class completionservicedemo{public static void Main (string[] args) thro WS interruptedexception,executionexception{/** * Internally maintains a thread pool of 11 threads */executorservice exec = Executors.newfixedthreadpool ( 11);/** * */final blockingqueue<future<integer>> queue = new linkedblockingdeque<future< for blocked queues with capacity of 10 Integer>> (10);//instantiation completionservicefinal completionservice<integer> completionservice = new ExecutorcompletionService<integer> (exec, queue);/** * Simulation instantly generates 10 tasks, and each task runs at an inconsistent time */for (int i = 0; i <; i++) {completionservice.su Bmit (New callable<integer> () {@Overridepublic Integer call () throws Exception{int ran = new Random (). Nextint (1000) ; Thread.Sleep (RAN); System.out.println (Thread.CurrentThread (). GetName () + "resting" + Ran); return ran;});} /** * Immediately outputs the result */for (int i = 0; i < i++) {try{//who first runs complete, returns future<integer> F = Completionservice.take () directly; System.out.println (F.get ());} catch (Interruptedexception e) {e.printstacktrace ();} catch (Executionexception e) {e.printstacktrace ()}} Exec.shutdown ();}}
Output Result:

Pool-1-thread-4 Rest 5252pool-1-thread-1 rest 5959pool-1-thread-10 rest 215215pool-1-thread-9 rest 352352pool-1-thread-5 Resting, 389389pool-1-thread-3 resting, 589589pool-1-thread-2 resting, 794794pool-1-thread-7 resting, 805805pool-1-thread-6 resting. 909909pool-1-thread-8 rested 987987.

The first run completed direct return, do not need to be in the order of the task submitted, assuming the need to write a high concurrency program, and each task needs to return the results of the operation, this is a very good choice!


2, Executorservice.invokeall

Executorservice's InvokeAll method can also run the task in batches and return the results in bulk, but there is a disadvantage that I think is very fatal, must wait for the whole task to be completed after the unified return, on the one hand, memory holding time is long; After all, we all like to look at the output of the running results of the brush, rather than waiting hard;

Here's a sample example:

Package Com.zhy.concurrency.executors;import Java.util.arraylist;import Java.util.list;import java.util.Random; Import Java.util.concurrent.callable;import Java.util.concurrent.executionexception;import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import java.util.concurrent.Future; public class Testinvokeall{public static void Main (string[] args) throws interruptedexception,executionexception{ Executorservice exec = Executors.newfixedthreadpool (10); list<callable<integer>> tasks = new arraylist<callable<integer>> (); callable<integer> task = null;for (int i = 0; i <; i++) {task = new callable<integer> () {@Overridepublic I Nteger call () throws Exception{int ran = new Random (). Nextint (1000); Thread.Sleep (RAN); System.out.println (Thread.CurrentThread (). GetName () + "resting" + Ran); return ran;}; Tasks.add (Task);} Long s = System.currenttimemillis (); list<future<integer>> results = Exec.invokeall (tasks); System.out.println ("Run task consumed:" + (System.currenttimemillis ()-s) + "MS"), for (int i = 0; i < results.size (); i++) {try{system.out.println (R Esults.get (i). get ()); catch (Exception e) {e.printstacktrace ();}} Exec.shutdown ();}}

Operation Result:

pool-1-thread-10 Rest 1pool-1-thread-5 rest 59pool-1-thread-6 rest 128pool-1-thread-1 rest 146pool-1-thread-3 rest 158pool-1-thread-7 Rest 387pool-1-thread-9 rest 486pool-1-thread-8 rest 606pool-1-thread-4 rest 707pool-1-thread-2 rest 817 running task consumed: 819 Ms 146817158707591283876064861

I deliberately after the completion of the task to print a time, and then InvokeAll run finished printing the next time, it can be seen that InvokeAll return is waiting for all threads to finish running. In this regard, I think usability is inferior to completionservice.


Well, for the batch run task, and carry the return results of the case is here ~ if there is doubt or error in the code, please indicate ~




Java concurrency topic with return results for batch task run Completionservice Executorservice.invokeall

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.