how to run the main thread after all child threads have completed there exceution

。_饼干妹妹 提交于 2020-12-04 05:03:01

问题


I have a requirement in which 28 threads have to complete some functionality. I have created these threads as in anonymous inner classes like :

Thread t=new Thread(new Runnable(){public void run() 
                        {//code
                        }}
                                );

                        t.start();

Now I want that the further execution should start after all these threads have finished there work.

Note : I am confused about join() method as it makes my threads run sequentially.

So can anyone suggest me how can I make main thread run once these threads are done with work.


回答1:


Note : I am confused about join() method as it makes my threads run sequentially.

It will do that if you have code like this:

for (Runnable runnable : runnables) {
    Thread t = new Thread(runnable);
    t.start();
    t.join();
}

However, you can start all the threads you want to run in parallel, then call join on them all. For example:

List<Thread> threads = new ArrayList<>();
for (Runnable runnable : runnables) {
    Thread t = new Thread(runnable);
    t.start();
    threads.add(t);
}
// Now everything's running - join all the threads
for (Thread thread : threads) {
     thread.join();
}

// Now you can do whatever you need to after all the
// threads have finished.

There are many other approaches, of course - starting threads directly may well not be as suitable in your code as using a higher level abstraction; it depends on what you're trying to achieve. The above should work fine though - assuming all the Runnables are able to run in parallel without blocking each other through synchronization.




回答2:


Make use of CountDownLatch.

public static void main(String... args) {
    final CountDownLatch latch = new CountDownLatch(28);
    for(int i=0;i<28;i++) {
        Thread t=new Thread(new Runnable(){
                        public void run() 
                        {
                            try {
                                //code
                            } finally {
                                latch.countDown();
                            }
                        }
        });

        t.start();

    }
    latch.await();
    // Continue Code
}



回答3:


Use a CountDownLatch and wait for all your threads to complete. :) .

PS : I gotto agree, using join() is also correct and more efficient.

example code :

public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("t1 : " + i);
            }

        }
    });
    t1.start();
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("t2 : " + i);
            }

        }
    });
    t2.start();
    t1.join();
    t2.join();
    System.out.println("main");

}

O/P :

t1 : 0
t1 : 1
t2 : 0
t1 : 2
t1 : 3
t2 : 1
t1 : 4
t1 : 5
t2 : 2
t1 : 6
t1 : 7
t2 : 3
t1 : 8
t1 : 9
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
main



回答4:


According to the behaviour you're giving for join, I'm guessing you're starting and joining the threads within a single loop.

If you check the javadoc on this page, you'll note that a call to join will halt the execution of the calling thread until the other thread has finished executing.

You might want to keep an array or a list of threads when creating them, and starting them all in one loop, and only then joining them all.

Thread[] workers = new Thread[28];
for (int i = 0; i < workers.length; i++) {
    workers[i] = new Thread { ... };
}
// Start running all threads
for (Thread worker: workers) {
    worker.start();
}
// Make sure all threads are completed
for (Thread worker: workers) {
    worker.join(); // if the worker already stopped, it'll return immediately.
}
// Now all threads have finished running and you can start post-processing

It's not the most elegant solution, but it'll do the trick. As mentioned by others, you should probably use a CountDownLatch (haven't used one yet, so I can't provide feedback)

Edit: I've been beaten to it by Jon Skeet, sorry for the redundant answer...




回答5:


CountDownLatch is better option.

I have created dummy program. In this program I am sum 1000 number. I created 10 thread. In main thread I am doing dome of all child thread sum. you will get understand to simply viewing the code.

package Test1;

import java.util.concurrent.CountDownLatch;

class Sum extends Thread {
    private int from;
    private int to;
    private int sum = 0;
    CountDownLatch latch;

    public int getSum() {
        return sum;
    }

    public Sum(int from, int to, CountDownLatch latch) {
        this.from = from;
        this.to = to;
        this.latch = latch;
    }

    public void run() {
        for (int i = from; i < to; i++) {
            sum += i;
        }
        latch.countDown();
    }

}

public class Test5 {

    public static void main(String[] args) throws InterruptedException {

        int n = 1000;
        int tn = 10;
        int from = 1;
        int to;
        int sum = 0;
        Sum[] sumArray = new Sum[tn];
        final CountDownLatch latch = new CountDownLatch(tn);
        for (int i = 0; i < tn; i++) {
            to = from + n / tn;
            Sum s = new Sum(from, to, latch);
            sumArray[i] = s;
            s.start();
            from = to;
        }

        // Thread.sleep(1000);
        latch.await();
        for (int i = 0; i < tn; i++) {
            sum += sumArray[i].getSum();
        }
        System.out.println(sum);
    }
}


来源:https://stackoverflow.com/questions/28164990/how-to-run-the-main-thread-after-all-child-threads-have-completed-there-exceutio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!