Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何知道两个线程中哪个线程先完成执行_Java_Multithreading - Fatal编程技术网

Java 如何知道两个线程中哪个线程先完成执行

Java 如何知道两个线程中哪个线程先完成执行,java,multithreading,Java,Multithreading,我有两个线程A和B。如果A首先完成,那么我必须执行函数1,否则如果B首先完成,我需要执行函数2。如何知道这两个线程中的哪一个先完成了执行?您可以使用以下命令,只有在前一个值为null时才会设置该命令。(即使只有一个线程,也可以使用此选项,以确保设置后不会更改值) AtomicReference ref=新的AtomicReference(); 参考比较数据集(空,值); 此解决方案的优点是,第一个线程完成后就有赢家,而不必等到所有线程完成 编辑: jtahlborn表示的Aa,CountDow

我有两个线程A和B。如果A首先完成,那么我必须执行函数1,否则如果B首先完成,我需要执行函数2。如何知道这两个线程中的哪一个先完成了执行?

您可以使用以下命令,只有在前一个值为null时才会设置该命令。(即使只有一个线程,也可以使用此选项,以确保设置后不会更改值)

AtomicReference ref=新的AtomicReference();
参考比较数据集(空,值);
此解决方案的优点是,第一个线程完成后就有赢家,而不必等到所有线程完成

编辑:

jtahlborn表示的Aa,
CountDownLatch
是这个问题的更好的抽象。因此,相同的算法可以写成这样:

import java.util.concurrent.CountDownLatch;

public class ThreadTest {
    private CountDownLatch latch = new CountDownLatch(1);
    private String winner;

    private synchronized void finished(String threadName) {
        if (winner == null) {
            winner = threadName;
        }
        latch.countDown();
    }

    public void run() {
        Runnable r1 = new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (5000 * Math.random()));
                }
                catch (InterruptedException e) {
                    // ignore
                }
                finally {
                    finished("thread 1");
                }
            }
        };

        Runnable r2 = new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (5000 * Math.random()));
                }
                catch (InterruptedException e) {
                    // ignore
                }
                finally {
                    finished("thread 2");
                }
            }
        };

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
        try {
            latch.await();
            System.out.println("The winner is " + winner);
        }
        catch (InterruptedException e) {
            System.out.println("No winner");
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String[] args) {
        new ThreadTest().run();
    }
}
如果要在显示赢家之前等待两个线程完成,只需将闩锁初始化为2而不是1。

可能的解决方案之一。有一些共享的标志变量

import java.util.concurrent.atomic.AtomicInteger;

final AtomicInteger winner = new AtomicInteger(0);
然后在第一个线程的run()方法调用结束时

winner.compareAndSet(0, 1);
在第二个线程中

winner.compareAndSet(0, 2);
这样,原子整数将只允许在首先调用compareAndSet的线程中设置非零值

然后,您可以使用

winner.get()

在生产代码中,我建议使用一些常量作为初始值和线程索引。

可能的重复项我将对此进行表决,认为这是一个好的答案,但我不确定为什么您使用信号量而不是简单的等待/通知。@jtahlborn:因为信号量提供了比synchronized/wait/notify更高的抽象,实际上,我认为信号量是一个更容易混淆的抽象概念,经常被滥用。信号量用于分配资源。在这种情况下使用它比简单的等待/通知更容易混淆。如果您想要更高级别的抽象,倒计时锁存器可能会更有意义。这是一个很好的解决方案,只是它不允许主线程等待结果。不,但是join()可以做到这一点,而且是相当标准的。如果您想避免使用join(),等待的线程可以忙着等待,或者您可以使用带有add()和take()的BlockingQueue来获得第一个答案,而不是等待其他线程完成。
winner.compareAndSet(0, 2);
winner.get()