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
- Long Tstart = System.currenttimemillis ();
- System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
- for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
- Runnable r = New Runnable () {
- @Override
- Public void Run () {
- System.out.println (Thread.CurrentThread (). GetName () + "Start");
- Do something ...
- System.out.println (Thread.CurrentThread (). GetName () + "end.");
- }
- }
- Thread t = new Thread (r);
- T.start ();
- }
- System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
- Long tEnd = System.currenttimemillis ();
- 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
- Public class Importthread extends Thread {
- Private static list<thread> runningthreads = new arraylist<thread> ();
- Public Importthread () {
- }
- @Override
- Public void Run () {
- Regist (this); Register when thread starts
- System.out.println (Thread.CurrentThread (). GetName () + "start ..."); Print start tag
- Do something ...
- Unregist (this); Unregister at end of thread
- System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
- }
- Public void Regist (Thread t) {
- synchronized (runningthreads) {
- Runningthreads.add (t);
- }
- }
- Public void Unregist (Thread t) {
- synchronized (runningthreads) {
- Runningthreads.remove (t);
- }
- }
- Public Static Boolean hasthreadrunning () {
- Return (Runningthreads.size () > 0); By judging if runningthreads is empty, you can know if the thread is still not finished.
- }
- }
Code in main thread:
Java code
- Long Tstart = System.currenttimemillis ();
- System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
- for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
- Thread t = new Importthread ();
- T.start ();
- }
- while (true) {//waits for all child threads to finish executing
- if (! Importthread.hasthreadrunning ()) {
- Break
- }
- Thread.Sleep (500);
- }
- System.out.println (Thread.CurrentThread (). GetName () + "end."); //Print end tag
- Long tEnd = System.currenttimemillis ();
- 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
- Public class Mycountdown {
- private int count;
- Public Mycountdown (int count) {
- This.count = count;
- }
- Public synchronized Void Countdown () {
- count--;
- }
- Public synchronized boolean hasnext () {
- Return (Count > 0);
- }
- public int GetCount () {
- return count;
- }
- Public void SetCount (int count) {
- This.count = count;
- }
- }
Importthread class
Java code
- Public class Importthread extends Thread {
- Private Mycountdown C;
- Public Importthread (Mycountdown c) {
- THIS.C = C;
- }
- @Override
- Public void Run () {
- System.out.println (Thread.CurrentThread (). GetName () + "start ..."); Print start tag
- Do something
- C.countdown (); //timer minus 1
- System.out.println (Thread.CurrentThread (). GetName () + "end. There are "+ c.getcount () + " Threads "); //Print end tag
- }
- }
In the main thread
Java code
- System.out.println (Thread.CurrentThread (). GetName () + "start"); Print start tag
- Mycountdown C = new Mycountdown (threadnum); Initialize Countdown
- for (int II = 0; ii < threadnum; ii++) {//Open Threadnum threads
- Thread t = new Importthread (c);
- T.start ();
- }
- while (true) {//waits for all child threads to finish executing
- if (!c.hasnext ()) break ;
- }
- 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
- Public class Importthread extends Thread {
- Private Countdownlatch threadssignal;
- Public Importthread (Countdownlatch threadssignal) {
- This.threadssignal = threadssignal;
- }
- @Override
- Public void Run () {
- System.out.println (Thread.CurrentThread (). GetName () + "start ...");
- Do somethings
- Threadssignal.countdown (); //The counter minus 1 at end of thread
- System.out.println (Thread.CurrentThread (). GetName () + "end. There are "+ threadssignal.getcount () + " Threads ");
- }
- }
In the main thread
Java code
- countdownlatch threadsignal = new Countdownlatch (threadnum); //initialize countdown
- for (int ii = 0; ii < threadnum; ii++) {//open threadnum threads
- final iterator<string> itt = It.get (ii);
- thread t = new importthread ( itt,sql,threadsignal);
- T.start ();
- }
- Threadsignal.await (); //waits for all child threads to finish executing
- 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