Java Multithreading--Let the main thread wait for all the child threads to finish executing

Source: Internet
Author: User

The amount of data is very large millions records, so considering to use multi-threaded concurrent execution, in the process of writing encountered problems, I would like to count all the child process execution completed a total of time, before the first child process was created before the current date with System.currenttimemillis () At the end of the last subprocess, the current time is recorded, and two times a minus gets the difference in total, the code is as follows

Java code
  1. Long Tstart = System.currenttimemillis ();
  2. System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
  3. for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
  4. Runnable r = New Runnable () {
  5. @Override
  6. Public void Run () {
  7. System.out.println (Thread.CurrentThread (). GetName () + "Start");
  8. Do something ...
  9. System.out.println (Thread.CurrentThread (). GetName () + "end.");
  10. }
  11. }
  12. Thread t = new Thread (r);
  13. T.start ();
  14. }
  15. System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
  16. Long tEnd = System.currenttimemillis ();
  17. System.out.println ("Total time:" + (Tend-tstart) + "millions");


The result is a statement that takes the main thread to print out almost instantaneously at the end of the for loop, because all of the child threads are executing concurrently and their main thread is running, which raises the question of how this article title "Let the main thread wait for all child threads to complete." Try to add t.join () after each child thread starts, and the result is that all threads are executed sequentially, which loses the concurrency meaning, which is obviously not what I want.
Google on the internet for a long time did not find a solution, have no one encountered such a demand? Or is this question too simple? No resistance had to find a way ...
Finally my workaround is to customize a Importthread class that inherits from Java.lang.Thread, overloads the Run () method, and saves all the resulting threads with a list property, So as long as the list is empty to know whether there are no child threads are not finished, the class code is as follows:

Java code
  1. Public class Importthread extends Thread {
  2. Private static list<thread> runningthreads = new arraylist<thread> ();
  3. Public Importthread () {
  4. }
  5. @Override
  6. Public void Run () {
  7. Regist (this); Register when thread starts
  8. System.out.println (Thread.CurrentThread (). GetName () + "start ..."); Print start tag
  9. Do something ...
  10. Unregist (this); Unregister at end of thread
  11. System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
  12. }
  13. Public void Regist (Thread t) {
  14. synchronized (runningthreads) {
  15. Runningthreads.add (t);
  16. }
  17. }
  18. Public void Unregist (Thread t) {
  19. synchronized (runningthreads) {
  20. Runningthreads.remove (t);
  21. }
  22. }
  23. Public Static Boolean hasthreadrunning () {
  24. Return (Runningthreads.size () > 0); By judging if runningthreads is empty, you can know if the thread is still not finished.
  25. }
  26. }


Code in main thread:

Java code
  1. Long Tstart = System.currenttimemillis ();
  2. System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
  3. for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
  4. Thread t = new Importthread ();
  5. T.start ();
  6. }
  7. while (true) {//waits for all child threads to finish executing
  8. if (! Importthread.hasthreadrunning ()) {
  9. Break
  10. }
  11. Thread.Sleep (500);
  12. }
  13. System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
  14. Long tEnd = System.currenttimemillis ();
  15. System.out.println ("Total time:" + (Tend-tstart) + "millions");


The result of the printing is:
Main start
Thread-1 start ...
Thread-5 start ...
Thread-0 start ...
Thread-2 start ...
Thread-3 start ...
Thread-4 start ...
Thread-5 ended.
Thread-4 ended.
Thread-2 ended.
Thread-0 ended.
Thread-3 ended.
Thread-1 ended.
Main ends.
Total Elapsed Time: 20860millions
You can see that the main thread is not executed until all the child threads have been executed.
================================================== The following is the second edit ===============================================
The method aboveThere is a hidden danger: If thread 1 starts and ends, and the other thread has not started at this point, the size of the runningthreads is also 0, and the main thread will assume that all threads have finished executing. The workaround is to replace the list type runningthreads with a counter of a non-trivial type, and the value of the counter should be set before the thread is created.
Mycountdown class

Java code
  1. Public class Mycountdown {
  2. private int count;
  3. Public Mycountdown (int count) {
  4. This.count = count;
  5. }
  6. Public synchronized Void Countdown () {
  7. count--;
  8. }
  9. Public synchronized boolean hasnext () {
  10. Return (Count > 0);
  11. }
  12. public int GetCount () {
  13. return count;
  14. }
  15. Public void SetCount (int count) {
  16. This.count = count;
  17. }
  18. }


Importthread class

Java code
  1. Public class Importthread extends Thread {
  2. Private Mycountdown C;
  3. Public Importthread (Mycountdown c) {
  4. THIS.C = C;
  5. }
  6. @Override
  7. Public void Run () {
  8. System.out.println (Thread.CurrentThread (). GetName () + "start ..."); Print start tag
  9. Do something
  10. C.countdown (); //timer minus 1
  11. System.out.println (Thread.CurrentThread (). GetName () + "end. There are "+ c.getcount () + " Threads "); //Print end tag
  12. }
  13. }


In the main thread

Java code
  1. System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
  2. Mycountdown C = new Mycountdown (threadnum); Initialize Countdown
  3. for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
  4. Thread t = new Importthread (c);
  5. T.start ();
  6. }
  7. while (true) {//waits for all child threads to finish executing
  8. if (!c.hasnext ()) break ;
  9. }
  10. System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag


Printing results:
Main start
Thread-2 start ...
Thread-1 start ...
Thread-0 start ...
Thread-3 start ...
Thread-5 start ...
Thread-4 start ...
Thread-5 ended. There are 5 more threads
Thread-1 ended. There are 4 more threads
Thread-4 ended. There are 3 more threads
Thread-2 ended. There are 2 more threads
Thread-3 ended. There are 1 more threads
Thread-0 ended. There are 0 more threads
Main ends.
more simple.Method: Use Java.util.concurrent.CountDownLatch instead of Mycountdown, use the await () method instead of while (true) {...}
Importthread class

Java code
  1. Public class Importthread extends Thread {
  2. Private Countdownlatch threadssignal;
  3. Public Importthread (Countdownlatch threadssignal) {
  4. This.threadssignal = threadssignal;
  5. }
  6. @Override
  7. Public void Run () {
  8. System.out.println (Thread.CurrentThread (). GetName () + "start ...");
  9. Do somethings
  10. Threadssignal.countdown (); //The counter minus 1 at end of thread
  11. System.out.println (Thread.CurrentThread (). GetName () + "end.  There are "+ threadssignal.getcount () + " Threads ");
  12. }
  13. }


In the main thread

Java code
    1. countdownlatch threadsignal = new  Countdownlatch (threadnum); //initialize countdown  
    2. for  (int ii = 0;  ii < threadnum; ii++)  {//open threadnum threads   
    3. final iterator<string> itt =  It.get (ii);   
    4. thread t = new importthread ( itt,sql,threadsignal);   
    5. T.start ();   
    6. }  
    7. Threadsignal.await (); //waits for all child threads to finish executing   
    8. System.out.println (Thread.CurrentThread (). GetName ()  + //print end tag   


Printing results:
Main start
Thread-1 start ...
Thread-0 start ...
Thread-2 start ...
Thread-3 start ...
Thread-4 start ...
Thread-5 start ...
Thread-0 ended. There are 5 more threads
Thread-1 ended. There are 4 more threads
Thread-4 ended. There are 3 more threads
Thread-2 ended. There are 2 more threads
Thread-5 ended. There are 1 more threads
Thread-3 ended. There are 0 more threads
Main ends.

Java Multithreading--Let the main thread wait for all the child threads to finish executing

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.