首页 > 解决方案 > 并行线程需要到达一个点,等待另一个线程,然后恢复 - 最好的方法?

问题描述

这是(简化的)场景:

什么是解决这个问题的好工具或设计?

到目前为止,我看到的并发和信号量示例似乎只处理 2 个线程,或者假设并行线程正在做类似的事情,但只是共享一个 var 或消息传递。我还没有找到任何适用于上述场景的东西。我正在继续研究它,并将更新任何发现。

如果不需要让其他线程退出,则 CountDownLatch 可能会起作用。或者如果它可以反向工作 - 让n线程等到线程 D 退出。

我对并发相当陌生(大学课程不会在它需要的任何时间提供它),所以请耐心等待。如果有类似问题的人偶然发现此线程,请在此处删除此链接:HowToDoInJava - Concurrency

标签: javamultithreadingconcurrency

解决方案


我会使用移相器

import java.util.concurrent.Phaser;

class Scratch {
    public static class ThreadABCWorker implements Runnable {
        String threadName;
        Phaser phaser;

        public ThreadABCWorker(String threadName, Phaser phaser) {
            this.threadName =  threadName;
            this.phaser = phaser;
        }

        @Override
        public void run() {
            System.out.println("Thread " + threadName + " has started");
            // do steps 1-7 as part of phase 0
            phaser.arriveAndAwaitAdvance();
            // All the work for phase 1 is done in Thread D, so just arrive again and wait for D to do its thing
            phaser.arriveAndAwaitAdvance();
            System.out.println("Continue Thread" + threadName);
        }
    }


    public static void main(String[] args) {
        var phaser = new Phaser(4);
        var threadA = new Thread(new ThreadABCWorker("A", phaser));
        var threadB = new Thread(new ThreadABCWorker("B", phaser));
        var threadC = new Thread(new ThreadABCWorker("C", phaser));
        var threadD = new Thread(() -> {
            phaser.arriveAndAwaitAdvance(); // D shouldn't start doing its thing until phase 1
            System.out.println("Thread D has started");

            try {
                System.out.println("sleep 100");
                Thread.sleep(100);
                System.out.println("Thread D has finished");
                phaser.arriveAndDeregister(); // All done, let ths other threads continue
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
    }
}

示例输出:

Thread A has started
Thread C has started
Thread B has started
Thread D has started
sleep 100
Thread D has finished
Continue ThreadB
Continue ThreadA
Continue ThreadC

推荐阅读