简体   繁体   English

主线程等待两个并行线程子 java

[英]Main thread to wait two parallel threads children java

first what i am trying to do:首先我想做的是:

During the main thread execution i want to pause the main thread and start two parallel threads.在主线程执行期间,我想暂停主线程并启动两个并行线程。 As soon as both this parallel threads terminate, i'd like to start again with the main thread.一旦这两个并行线程终止,我想从主线程重新开始。

What i tried:我尝试了什么:

    ...
    ...
    main thread is executing
    ...
    ...
CyclicBarrier barrier = new CyclicBarrier(2);
Thread child1 = new Thread(new ThreadBuilderTask(barrier,0));
Thread child2 = new Thread(new ThreadBuilderTask(barrier,1));

child1.start();
child2.start(); 

/* Now i'm expecting that child1 and child2 are running in parallel calling their fooFunction */

child1.join();
child2.join(); 
/*Now i'm expecting that main thread will wait for child1and also for child2 (that are running in parallel).*/

... main thread starts again after both child1 and child2 finished (reached the await of the barrier) 
... (break point set here, never reached)
...

Thread builder custom class螺纹生成器定制 class

public class ThreadBuilderTask implements Runnable{
    private CyclicBarrier barrier;
    private int index;
    ...setters and getters..

    @Override
    public void run() {
        fooFunction(this.getIndex());
        try {
            this.getBarrier().await();
        } catch (InterruptedException | BrokenBarrierException e) {
            return;
        }
    }

    public ThreadBuilderTask(CyclicBarrier barrier,int index){
      this.barrier = barrier;
      this.index = index;
    }

    public fooFunction(int index){
        //Something taking some seconds to execute
    }

It's not clear what is happening here but it is definetely not working.目前尚不清楚这里发生了什么,但它肯定不起作用。 As soon as i call join everything stops and the main thread never restart.一旦我调用加入,一切都会停止,主线程永远不会重新启动。 (I put a breakpoint after the joins to see when the main thread restarts). (我在连接之后放置了一个断点,以查看主线程何时重新启动)。

Maybe there is a bit of confusion with these concepts and also i'm not sure if i need to use both the barrier and the joins or simply one of those techniques.也许这些概念有点混乱,而且我不确定我是否需要同时使用屏障和连接,或者只是其中一种技术。

Thanks谢谢

Davide戴维德

You may consider to use Java CompletableFuture to achieve the objective.您可以考虑使用 Java CompletableFuture来实现目标。

Using its functions like supplyAsync or runAsync you may start child threads and join their respective result in the end.使用其诸如supplyAsyncrunAsync 之类的功能,您可以启动子线程并最终加入它们各自的结果。 Or you can simply let the main thread wait until the subsequent threads completes.或者您可以简单地让主线程等待,直到后续线程完成。

Recently I managed to implement a sample scatter-gather function using the same class.最近,我设法使用相同的 class 实现了一个示例分散收集 function。

Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

As mentioned in the comments I'd also suggest to use CompletableFuture .正如评论中提到的,我还建议使用CompletableFuture A very basic example of your described requirements could look like this:您描述的要求的一个非常基本的示例可能如下所示:

final Runnable runnable1 = ...;
final Runnable runnable2 = ...;

CompletableFuture<Void> future1 = CompletableFuture.runAsync(runnable1);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(runnable2);

CompletableFuture.allOf(future1, future2).get(); // waits for both runnables to finish

You might want to add more/some exception handling to this example.您可能希望在此示例中添加更多/一些异常处理。 But it should give an idea how this might work.但它应该给出一个想法,这可能是如何工作的。

First of all, it's worth analyzing why your program does not give you the desired output.首先,值得分析一下为什么你的程序没有给你想要的 output。 The main thread creates 2 child threads and completes.主线程创建2个子线程并完成。 If you want to wait till two child threads are completed, then you have to call barrier.await();如果你想等到两个子线程完成,那么你必须调用barrier.await(); in your main thread after starting the two child threads.在启动两个子线程后在您的主线程中。 This will keep your main thread blocking until two child threads complete.这将使您的主线程一直阻塞,直到两个子线程完成。

child1.start();
child2.start();

barrier.await();

Nonetheless, CountDownLatch is a much better candidate for your usecase.尽管如此, CountDownLatch对于您的用例来说是一个更好的候选者。 Just pass a latch to each child thread which does the computation and upon successful completion counts down the latch.只需将一个锁存器传递给执行计算的每个子线程,并在成功完成后对锁存器进行倒计时。 The main thread creates two threads, starts them and call await() on the latch, which blocks the main thread until two child threads completed.主线程创建两个线程,启动它们并在闩锁上调用await() ,这会阻塞主线程,直到两个子线程完成。 Once the latch reaches it's terminal state the await method returns and the main thread continues it's execution.一旦闩锁到达它的终端 state, await方法返回并且主线程继续执行它。 Here's how it looks.这是它的外观。

public class ThreadBuilderTask implements Runnable {
    private CountDownLatch latch;
    private int index;

    public ThreadBuilderTask(CountDownLatch latch, int index) {
        this.latch = latch;
        this.index = index;
    }

    @Override
    public void run() {
        fooFunction(index);
        latch.countDown();

    }

    public void fooFunction(int index) {
        // Something taking some seconds to execute

    }
}


final CountDownLatch completionLatch = new CountDownLatch(2);
Thread child1 = new Thread(new ThreadBuilderTask(continuationLatch, 0));
Thread child2 = new Thread(new ThreadBuilderTask(continuationLatch, 1));

child1.start();
child2.start();

completionLatch.await();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM