In multi-threaded applications, this scenario is often encountered: subsequent processing, depending on the results of the previous n-thread processing, must wait until the previous thread finishes executing before the code is allowed to execute.
Before I know cyclicbarrier, the easiest thing to think about is to put a common static variable, if there are 10 threads, each thread has finished processing up the results, and then a dead loop (or similar to the thread blocking method), to count the result, reached 10, It means that everyone is finished, and can carry on the following things, although the idea of the Earth turtle, but basically language-independent, almost all mainstream programming language support.
Package Yjmyzz.test;public class Threadlocktest {public static int flag = 0;//common variable publicly static void main (string[] args) throws Exception {threadlocktest testobj = new Threadlocktest (); Final int threadnum = 10; for (int i = 0; i < threadnum; i++) {New Thread (new myrunable (I, Testobj)). Start (); } while (true) {if (Testobj.flag >= threadnum) {System.out.println ("-----------\ n All t Hread Execution Complete! "); Break } thread.sleep (10); }} Static Class Myrunable implements Runnable {int _i = 0; Threadlocktest _test; Public myrunable (int i, threadlocktest test) {this._i = i; This._test = test; @Override public void Run () {try {Thread.Sleep ((long) (Math.random () * 10)); SYSTEM.OUT.PRINTLN ("thread" + _i + "done"); Using synchronized to obtain a synchronous lock Synchronized (_test) {_test.flag + = 1; } System.out.println ("thread" + _i + "= +" + _test.flag);//test} catch (Exception e) { E.printstacktrace (); } } }}
Output Result:
Thread 0 Done
Thread 0 = 1
Thread 9 Done
Thread 9 = 2
Thread 1 Done
Thread 1 = 3
Thread 3 Done
Thread 3 = 4
Thread 7 Done
Thread 7 = 5
Thread 6 Done
Thread 6 = 6
Thread 2 Done
Thread 2 = 7
Thread 4 Done
Thread 4 = 8
Thread 8 Done
Thread 8 = 9
Thread 5 Done
Thread 5 = 10
-----------
All Thread execution Complete!
In addition to this method, Futuretask can be used to achieve a similar effect, and its get method blocks the thread until the asynchronous processing is complete. The disadvantage is that the futuretask call is callable, must have a return value, so even if you do not want to return the value, you have to return a point what
Package Yjmyzz.test;import Java.util.concurrent.callable;import Java.util.concurrent.executionexception;import Java.util.concurrent.futuretask;public class Futuretasktest {public static void main (string[] args) throws Executionex Ception, interruptedexception {futuretask<string>[] tasks = new FUTURETASK[10]; for (int i = 0; i < tasks.length; i++) {final int j = i; Tasks[i] = new futuretask<string> (new callable<string> () {@Override public stri Ng call () throws Exception {Thread.Sleep ((long) (Math.random () * 100)); Return "task" + j + "done"; } }); New Thread (Tasks[i]). Start (); } for (int i = 0; i < tasks.length; i++) {System.out.println (Tasks[i].get ());//wait for all task execution to complete } System.out.println ("-----------\ n all task execution complete! "); }}
Execution Result:
Task0 Done
Task1 Done
Task2 Done
Task3 Done
Task4 Done
Task5 Done
Task6 Done
Task7 Done
Task8 Done
TASK9 Done
-----------
All Task execution Complete!
Of course, the most "orthodox" solution to this requirement should be to use Cyclicbarrier, which can set up a so-called "barrier Point" (or rendezvous point), like in a team activity where everyone is a thread, but before a task starts, everyone must first reach the meeting point, and after the collection is complete, To continue the task behind.
Package Yjmyzz.test;import Java.util.concurrent.cyclicbarrier;public class ThreadTest {public static void main (string[ ] args) throws Exception {Final int threadnum = 10; Cyclicbarrier cb = new Cyclicbarrier (threadnum + 1);//Note: 10 Child threads + 1 main thread for (int i = 0; i < threadnum; i++) { New Thread (New Myrunable (CB, I)). Start (); } cb.await (); System.out.println ("-----------\ n All thread execution complete! "); } Static class Myrunable implements Runnable {Cyclicbarrier _CB; int _i = 0; Public myrunable (cyclicbarrier cb, int i) {THIS._CB = CB; This._i = i; @Override public void Run () {try {Thread.Sleep ((long) (Math.random () * 100)); SYSTEM.OUT.PRINTLN ("thread" + _i + "done, waiting for other threads to finish ..."); _cb.await (); } catch (Exception e) {e.printstacktrace (); } } }}
Thread 9 done, waiting for other threads to finish ...
Thread 5 done, waiting for other threads to finish ...
Thread 0 done, waiting for other threads to finish ...
Thread 6 done, waiting for other threads to finish ...
Thread 4 done, waiting for other threads to finish ...
Thread 2 done, waiting for other threads to finish ...
Thread 3 done, waiting for other threads to finish ...
Thread 8 done, waiting for other threads to finish ...
Thread 7 done, waiting for other threads to finish ...
Thread 1 done, waiting for other threads to finish ...
-----------
All Thread execution Complete!
Reference article:
http://ifeve.com/concurrency-cyclicbarrier/
http://ifeve.com/thread-synchronization-utilities-5/
http://ifeve.com/semaphore-countdownlatch-cyclicbarrier-phaser-exchanger-in-java/
Java Concurrent Programming Learning: How to wait for multiple threads to complete before proceeding with subsequent processing (Futuretask, synchronized, cyclicbarrier)