The server receives a request, often requiring several simultaneous calculations or sending requests to other services, and the final assembly results are returned upstream. This article looks at the JDK to provide several parallel processing schemes, involving Excecutorservice/completionservice. The scenario to be implemented is that the request has a timeout limit, and if all operations are calculated, all are assembled back, otherwise only partially completed results are assembled.
1. Prerequisites
Task class, sleep represents the time-consuming calculation required for this computation, and returns a result of the calculation. public class MyTask implements callable<integer> { private int id; private int time; Public MyTask (int i, int time) { this.id = i; This.time = time; } @Override public Integer call () throws Exception { thread.sleep (time); return ID;} } Thread pool Executorservice threadPool = new Threadpoolexecutor (ten, A, timeunit.seconds, new arrayblockingqueue< Runnable> (100));
2. Tasks waiting one by one
Once the task is submitted, wait for the result to return.
Total 150ms timeout list<future<integer>> futures = new arraylist<future<integer>> (); Futures.add ( Threadpool.submit (New MyTask (1)), Futures.add (Threadpool.submit (New MyTask (2)), Integer res = 0;for (int i = 0; i < Futures.size (); ++i) {try {Integer tmp = Futures.get (i). Get (+ i *, timeunit.milleseconds); res + = tmp;} catch (Exception e) {//nothin G}}system.out.println (RES);
The print result is 0, actually the first calculation is completed at 60MS, which could have returned the first result. This is because producers and consumers correspond, scheduling improper.
3. Wait for decoupling
By using a queue to decouple the producer from the consumer, the producer puts the result in a queue, the consumer takes the result from the queue, and does not wait in the order of the task submission, as long as the results are consumed. Completionservice is the encapsulation of executor and asynchronous queues.
completionservice<integer> service = new executorcompletionservice<integer> (ThreadPool); List<future<integer>> futures = new arraylist<future<integer>> (); Futures.add ( Service.submit (New MyTask (1)); Futures.add (Service.submit (New MyTask (2, 150)); list<integer> result = new Arraylist<integer> (Futures.size ()); for (int i = 0; i < futures.size (); ++i) {
future<integer> future = Service.poll (+ i *, timeunit.milliseconds); if (null! = future) { Result.add (Future.get ());} } int res = 0;for (Integer i:result) { Res + = NULL = = I? 0:i;} System.out.println (RES);
The result of the printout is 1, which is the result of the first calculation. Whoever finishes first will take who.
4. Make the most of your time
The previous two scenarios set a fixed wait time for each task, and the sum of the two does not exceed the timeout limit. This does not make the best use of time, and the two tasks are mutually exclusive, and their respective available time should be the time-out and not the sum of the time-out. If the first task takes 140 and the second time is 60, the first two tasks can only get the results of the second task. If both are set to a timeout of 150, you can get 2 results.
list<mytask> tasks = new arraylist<mytask> (), Tasks.add (New MyTask (1), Tasks.add (New MyTask (2, 60)); List<future<integer>> futures = Threadpool.invokeall (tasks, timeunit.milliseconds), int res = 0;FOR ( Future<integer> future:futures) { System.out.println ("IsDone:" + future.isdone ()); System.out.println ("Iscancel:" + future.iscancelled ()); if (future.iscancelled ()) { continue; } Res + = Future.get ();} System.out.println (RES);
The print result is 3. The above method takes advantage of Executorservice's InvokeAll method, where all tasks are completed or waiting for time-outs to return, and when timeouts cancel tasks that have not yet been completed, determine whether the task is completed by judging whether the task is canceled.
This article is about scenarios where results can be returned with no effect. If the results need to be merged in a sequential order, or if you just wait for a calculation to complete, you don't necessarily need scenario 3.
Java Batch processing Executorservice/completionservice