Requirement: A concurrent execution of three threads is required to return the result within a specified time, or null if a line blocks until those.
Idea: Use Executorservice's InvokeAll (Time,timeuint) method to set the execution time limit, the method returns a List<future<t>>, and once returned, cancels the unfinished task, It then reads the future from the list and calls the Future.get () method to get the result returned by the thread, and if Future.get () throws a cancellationexception it means that the task is not completed and is canceled.
<T> list<future<t>> InvokeAll (collection<?extendsCallable<t>>Tasks,LongTimeout, timeunit unit)throwsInterruptedexception performs a given task, returning the future list of hold task status and results when all tasks are completed or when the time-out expires (whichever occurs first). Returns the Future.isdone () of all elements of the list astrue. Once returned, the unfinished task is canceled. Note that you can terminate a completed task either normally or by throwing an exception. If the given collection is modified while this operation is in progress, the result of this method is indeterminate. Parameters: Tasks-Task Collectiontimeout-Maximum wait time unit-the time unit of the timeout parameter returns: Represents the future list of tasks, in the same order as the iterators for a given task list. If the operation does not time out, all tasks have been completed. If it does, some tasks are not yet complete. Thrown: interruptedexception-If an interrupt occurs while waiting, in which case the unfinished task is canceled NullPointerException-If the task or any of its elements or unit isNULLrejectedexecutionexception-If all tasks cannot be scheduled for execution
Public classCallableandfuturetask {/** * @paramargs*/ Public Static classMycallableImplementsCallable<string>{ PrivateString name; Private intAge ; PublicMycallable (String name,intAge ) { //TODO auto-generated Constructor stub This. Name =name; This. Age =Age ; } @Override PublicString Call ()throwsException {//TODO auto-generated Method StubThread.Sleep (NewRandom (). Nextint (4000)); return"Name:" + This. name+ "" + "Age:" + This. Age; } } Public Static voidMain (string[] args) {//callable perform tasks, future gets task execution resultsExecutorservice ThreadPool = Executors.newfixedthreadpool (3); inti = 10; while(i--> 0) {//Create a list List of tasks<MyCallable> tasks =NewArraylist<mycallable>(); Tasks.add (NewMycallable ("Tom", 20)); Tasks.add (NewMycallable ("John", 30)); Tasks.add (NewMycallable ("Jack", 40));
Used to receive task execution results List<Future<String>> Taskresult =NULL; List<String> result =NewArraylist<string>(); System.out.println ("Wait Result:" +i); Long s=System.currenttimemillis (); Try{Taskresult= Threadpool.invokeall (Tasks, 3000, Timeunit.milliseconds); } Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } for(intj = 0; J < 3; J + +){ Try {Result.add (Taskresult.get (j). get ()); } Catch(cancellationexception e) {//TODO auto-generated Catch block//e.printstacktrace ();System.out.println (j+ "cancled"); }Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } Catch(executionexception e) {//TODO auto-generated Catch blockE.printstacktrace (); }} System.out.println ("Execution Time:" + (System.currenttimemillis ()-s)/1000); if(result.size () = = 0) {System.out.println ("Get No Data"); }Else{System.out.println (result); } } }}
Compared with the simple future callable, Executorservice's Submit method can not set a time limit, only use Future.get (Time,timeuint), but in this way, then receive the result becomes serial, That is, the result of receiving each task takes time, and the execution of three tasks becomes 3*time, which can be used for a single task setting timeout
PackageCom.newtechnologyinjava5;Importjava.util.ArrayList;Importjava.util.List;ImportJava.util.Random;Importjava.util.concurrent.Callable;Importjava.util.concurrent.CancellationException;ImportJava.util.concurrent.CompletionService;Importjava.util.concurrent.ExecutionException;ImportJava.util.concurrent.ExecutorCompletionService;ImportJava.util.concurrent.ExecutorService;Importjava.util.concurrent.Executors;Importjava.util.concurrent.Future;ImportJava.util.concurrent.FutureTask;ImportJava.util.concurrent.TimeUnit;Importjava.util.concurrent.TimeoutException; Public classCallableandfuturetask {/** * @paramargs*/ Public Static classMycallableImplementsCallable<string>{ PrivateString name; Private intAge ; PublicMycallable (String name,intAge ) { //TODO auto-generated Constructor stub This. Name =name; This. Age =Age ; } @Override PublicString Call ()throwsException {//TODO auto-generated Method StubThread.Sleep (NewRandom (). Nextint (4000)); return"Name:" + This. name+ "" + "Age:" + This. Age; } } Public Static voidMain (string[] args) {//callable perform tasks, future gets task execution resultsExecutorservice ThreadPool = Executors.newfixedthreadpool (3); inti = 10; while(i--> 0){ Future<String> Future1 = Threadpool.submit (NewMycallable ("Tom", 20)); Future<String> Future2 = Threadpool.submit (NewMycallable ("John", 30)); Future<String> future3 = Threadpool.submit (NewMycallable ("Jack", 40)); Try { Try{result.add (Future1.get (3000, timeunit.milliseconds)); } Catch(TimeoutException e) {//TODO auto-generated Catch blockFuture1.cancel (true); } Try{result.add (Future2.get (3000, timeunit.milliseconds)); } Catch(TimeoutException e) {//TODO auto-generated Catch blockFuture2.cancel (true); } Try{result.add (Future3.get (3000, timeunit.milliseconds)); } Catch(TimeoutException e) {//TODO auto-generated Catch blockFuture3.cancel (true); } } Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } Catch(executionexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } if(result.size () = = 0) {System.out.println ("Get No Data"); }Else{System.out.println (result); } } }}
The time-limit problem of Java multi-threaded batch execution