You need to implement a multithreaded concurrency business scenario, start several sub-threads, and finally end up with all the child threads running at the end. (Task WaitAll similar to. NET)
The Executorservice multithreaded programming model in Java provides a mechanism for introducing it through code.
Method One: Executorservice#awaittermination
/** * Blocks until all tasks has completed execution after a shutdown * request, or the timeout occurs, or the CU Rrent thread is * interrupted, whichever happens first. * * @param timeout The maximum time to wait * @param unit The time unit of the timeout argument * @return < tt>true</tt> If this executor terminated and * <tt>false</tt> If the timeout elapsed before Termination * @throws interruptedexception if interrupted while waiting * /Boolean awaittermination ( Long timeout, timeunit unit) throws Interruptedexception;
by Executorservice#submit (or execute) to join the child thread and start, the Awaittermination block waits for all child threads to finish executing.
Sample
Executorservice es = Executors.newcachedthreadpool (); list<future<string>> futurelist = Lists.newarraylist (); Futurelist.add (Es.submit (New Callable<String > () {@Overridepublic String call () throws Exception {System.out.println ("Threading1 is running"); Thread.Sleep (+); return "1";}}); Futurelist.add (Es.submit (new callable<string> () {@Overridepublic String call () throws Exception { System.out.println ("Threading2 is running"); Thread.Sleep (+); return "2";}}); Futurelist.add (Es.submit (new callable<string> () {@Overridepublic String call () throws Exception { System.out.println ("Threading3 is running"); Thread.Sleep (+); return "3";}}); Es.shutdown (); try {Boolean completed = Es.awaittermination (timeunit.milliseconds); System.out.println ("All Tasks Completed:" + completed);//es.wait (the future future:futurelist) {try {if ". IsDone ()) {System.out.println ("Result:" + future.get ());}} catch (Cancellationexception ex) {ex.printstacktrace ();} finally{Future.cancel (TRUE);}}} catch (Exception e) {e.printstacktrace ();}
Output Result:
Threading 1 is runningthreading 2 are runningthreading 3 is runningall tasks Completed:falseresult:1result:3
Only 1 and 3 output the result, because the Awaittermination timeout setting of Ms,threading2 simulates the MS, so the timeout is canceled. The Future#isdone () can be used to determine if the corresponding thread has finished processing.
In this scenario if isDone () = = False Then it can be thought that the timeout was eliminated.
It is important to note that after all the child threads have been added and started, the Executorservice#shutdown method is called: On the one hand, the new sub-thread "commit" is no longer accepted, on the other hand executorservice is actually a work thread, If not shutdown the current thread will not end. The difference can be seen when calling shutdown and not calling shutdown from main after running the console state.
Finally, the Future#cancel () is called in Finally, and the thread that is timed out is probably still running after the await, and is canceled directly.
Method Two: Executorservice#invokeall
InvokeAll is much like the overall packaging of the above implementation, but the details are slightly different. First, the callable is created in the list and handed to the InvokeAll method to execute and set the time-out.
Executorservice es = Executors.newcachedthreadpool (); list<callable<string>> tasks = Lists.newarraylist (); Tasks.add (new callable<string> () {@ Overridepublic String Call () throws Exception {System.out.println ("Threading 1 is Running"); Thread.Sleep (+); return "1";}}); Tasks.add (New callable<string> () {@Overridepublic String call () throws Exception {System.out.println ("threading 2 is running "); Thread.Sleep (+); return "2";}}); Tasks.add (New callable<string> () {@Overridepublic String call () throws Exception {System.out.println ("threading 3 is running "); Thread.Sleep (+); return "3";}}); Try {list<future<string>> futurelist = es.invokeall (tasks, n, timeunit.milliseconds); Es.shutdown (); for (future:futurelist) {try {if (Future.isdone ()) {System.out.println ("Result:" + future.get ());}} catch (Cancellationexception ex) {ex.printstacktrace ();}}} catch (Exception e) {e.printstacktrace ();}
Output Result:
Threading 1 is runningthreading 2 are runningthreading 3 is Runningresult:1result:3java.util.concurrent.cancellationexce Ption
All Future.isdone () are true after Executorservice#invokeall () is executed, and when Future.get () takes the result, the future that is timed out is thrown cancellationexception. Because the Future#cancel () method is called inside InvokeAll.
The source code is as follows:
Public <T> list<future<t>> InvokeAll (collection<? extends callable<t>> tasks, Long timeout, timeunit unit) throws Interruptedexception {if (tasks = = NULL | | un it = = null) throw new NullPointerException (); Long Nanos = Unit.tonanos (timeout); List<future<t>> futures = new arraylist<future<t>> (Tasks.size ()); Boolean done = false; try {for (callable<t> t:tasks) Futures.add (Newtaskfor (T)); Long lasttime = System.nanotime (); Interleave time checks and calls to execute in case//executor doesn ' t has any/much parallelism. Iterator<future<t>> it = Futures.iterator (); while (It.hasnext ()) {Execute ((Runnable) (It.next ())); Long now = System.nanotime (); Nanos-= Now-lasttime; Lasttime = Now if (Nanos <= 0) return futures; } for (future<t> f:futures) {if (!f.isdone ()) {if (Nanos <= 0) return futures; try {f.get (Nanos, timeunit.nanoseconds); } catch (Cancellationexception ignore) {} catch (Executionexception ignore) {} cat CH (timeoutexception toe) {return futures; } Long now = System.nanotime (); Nanos-= Now-lasttime; Lasttime = Now; }} done = true; return futures; } finally {if (!done) for (future<t> f:futures) F.cancel (true); } }
Of course, in the Executorservice programming model, its own definition of threading, through Countdownlatch control can also be achieved.
Java Executorservice Multithreading Practice (i)