我有两个线程A和B.如果A先完成,那么我必须执行function1 else如果B先完成,我需要执行函数2.我知道这两个线程中哪一个先完成了执行? / p>
答案 0 :(得分:2)
您可以使用以下内容,只有在前一个值为null时才会设置。 (即使你只有一个线程来确保一旦设置后值没有改变,也可以使用它)
AtomicReference<ValueType> ref = new AtomicReference<ValueType>();
ref.compareAndSet(null, value);
答案 1 :(得分:2)
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();
}
}
此解决方案的优势在于,只要第一个线程完成就可以获胜,而不必等到所有线程都完成。
编辑:
Jahlborn指出,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。
答案 2 :(得分:2)
(许多)可能的解决方案之一。有一些共享标志变量
import java.util.concurrent.atomic.AtomicInteger;
final AtomicInteger winner = new AtomicInteger(0);
然后在第一个线程
中线程的run()方法调用结束时winner.compareAndSet(0, 1);
第二个帖子中的
winner.compareAndSet(0, 2);
这样,原子整数只允许在首先调用compareAndSet的线程中设置非零值。
然后你可以用
获得执行结果作为胜利者指数winner.get()
在生产代码中,我建议使用一些常量作为初始值和线程索引。