【问题标题】:Join one of any threads in Java加入 Java 中的任何线程之一
【发布时间】:2017-01-30 07:29:28
【问题描述】:

在我的 Java 程序中,我将同时启动两个线程。我希望我的程序在两个线程之一完成时加入(),而无需等待两个线程完成。换句话说,如果线程 A 在线程 B 之前完成,我希望主线程加入线程 A 并恢复主线程而不等待线程 B 完成,反之亦然。

哪些 Java 类允许我这样做?

【问题讨论】:

  • 不要创建自己的线程,而是创建一个ExecutorService,并将您的任务传递给它的invokeAny 方法。

标签: java multithreading


【解决方案1】:

一个解决方案是使用CountDownLatch,通过让主线程等待其计数达到零,并让两个线程各自减少计数(在这种情况下,计数的初始值为 1 )。

【讨论】:

  • 我在我的程序中使用了 CountDownLatch,它完美地工作。谢谢。
【解决方案2】:
public static void main(String[] atrgs){
    Thread t1 = new Thread(new MyRunnable());
    Thread t2 = new Thread(new MyRunnable());
    t1.start();
    t2.start();
    while(t1.isAlive()&&t2.isAlive()){

    }
    System.out.println("main resumes");

}

【讨论】:

  • 但是使用while循环自旋主线程来实现线程同步并不是一种有效的线程同步技术。似乎它需要三个线程,每个线程两个线程,一个用于 while 循环的线程来检查两个线程。
  • 即使没有while循环也只有3个线程。但是,最好使用闩锁,因为闩锁.await() 仅用于此目的。如果您不想使用倒计时闩锁,我只是想分享更简单的方法。
【解决方案3】:

实际上,Java 中的任何类都允许您这样做,因为任何类的对象都可以用作等待通知的监视器。只需创建一个对象,在其上调用 wait() 并让您的线程在完成时通知该对象:

private class Foo implements Runnable {
    private final int id;
    private final Object monitor;
    public Foo(int id, Object monitor) {
        this.id = id;
        this.monitor = monitor;
    }
    @Override
    public void run() {
        try {
            Thread.sleep((long)(Math.random() * 10000));
        } catch (InterruptedException e) {
        }
        System.out.println(id + " finished");
        synchronized (monitor) {
            monitor.notify();
        }
    }
}

public static void main(String[] args) throws InterruptedException {
    final Object monitor = new Object();
    synchronized (monitor) {
        new Thread(new Foo(1, monitor)).start();
        new Thread(new Foo(2, monitor)).start();
        System.out.println("Main goes to sleep");
        monitor.wait();
    }
    System.out.println("Main is running");
}

第一个通知将解除对主线程的阻塞并继续运行。

我会说这是解决您问题的经典解决方案,尽管@AR.3 建议的解决方案不会那么冗长并且肯定会奏效。我只是想表明,即使是一个简单的监视器对象也足以满足您的需求。

【讨论】:

  • 这是解决问题的一种有趣方法。我使用了 CountDownLatch,因为就像你说的那样,它比这个解决方案更简洁,但感谢你分享这个。
猜你喜欢
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多