繁体   English   中英

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

[英]How to know which thread completes execution first out of two threads

我有两个线程A和B.如果A先完成,那么我必须执行function1 else如果B先完成,我需要执行函数2.我知道这两个线程中哪一个先完成执行?

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

AtomicReference<ValueType> ref = new AtomicReference<ValueType>();

ref.compareAndSet(null, value);
import java.util.concurrent.Semaphore;

public class ThreadTest {
    private Semaphore semaphore = new Semaphore(0);
    private String winner;

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

    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 {
            semaphore.acquire();
            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();
    }
}

该解决方案的优点是,一旦第一个线程完成就获得胜利,而不必等到所有线程都完成。

编辑:

由jtahlborn指出, 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);

然后在第一个线程中调用thread的run()方法结束

winner.compareAndSet(0, 1);

在第二个线程

winner.compareAndSet(0, 2);

这种方式原子整数只允许在首先调用compareAndSet的线程中设置非零值。

然后你可以获得执行结果作为胜利者指数

winner.get()

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

暂无
暂无

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

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