假設有多個執行緒試圖找到一個值,無論哪個執行緒首先找到它,都應該將輸出發送到主執行緒,并且所有其他執行緒都應該終止。例子 -
public class WorkerThread implements Runnable {
@Override
public void run() {
// some long task here, returns int value
}
}
public class Main {
public static void main(String[] args){
// initialize multiple worker threads here
// then get result from the thread that completes first
}
}
我查看了檔案并找到了 invokeAny ExecutorService但這將回傳任何已成功完成的執行緒的結果,不一定是第一個。
uj5u.com熱心網友回復:
正如@Andy Turner 所說,使用一個CompletionService:
public static class WorkerThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int nextInt = new Random().nextInt(10000);
try {
System.out.println("I will cost " nextInt " ms to finish job.--" Thread.currentThread().getName());
Thread.sleep(nextInt);
} catch (InterruptedException ite) {
System.out.println("I am interrupted.--" Thread.currentThread().getName());
return -1;
}
System.out.println("I am finish.--" Thread.currentThread().getName());
return nextInt;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nums = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nums);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
while (nums-- > 0) {
completionService.submit(new WorkerThread());
}
Integer firstValue = completionService.take().get();
System.out.println("FirstValue is " firstValue);
executorService.shutdownNow();
}
您可以在輸出中看到,只有一個執行緒會完成作業(因為只呼叫completionService#take一次),其他執行緒將被中斷并退出:
I will cost 8943 ms to finish job.--pool-1-thread-1
I will cost 9020 ms to finish job.--pool-1-thread-2
I will cost 5025 ms to finish job.--pool-1-thread-3
I am finish.--pool-1-thread-3
FirstValue is 5025
I am interrupted.--pool-1-thread-1
I am interrupted.--pool-1-thread-2
uj5u.com熱心網友回復:
您還可以使用CountDownLatch和ExecutorService來實作這一點。
創建計數 = 1 的 CountDownLatch 物件。
CountDownLatch latch = new CountDownLatch(1);
使用 ExecutorService 池執行執行緒并在所有執行緒中傳遞閂鎖。
workerThreadPool.execute(new WorkerThread(latch));
等待任何執行緒完成它的操作。
latch.await();
在執行緒運行的 finally 塊中,關閉閂鎖。
latch.countDown();
一旦任何執行緒 countDown 的閂鎖,執行緒池將停止所有其他執行緒并關閉。
workerThreadPool.shutdownNow();
完整的例子如下。
import static java.lang.Thread.sleep;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable
{
CountDownLatch _latch;
public WorkerThread(CountDownLatch latch)
{
_latch = latch;
}
@Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread1 " this.toString());
sleep(5000);
}
catch (InterruptedException ex)
{
System.out.println("thread1 interupted");
}
finally
{
System.out.println("Finished1 " this.toString());
_latch.countDown();
}
}
}
class WorkerThread2 implements Runnable
{
CountDownLatch _latch;
public WorkerThread2(CountDownLatch latch)
{
_latch = latch;
}
@Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread2 " this.toString());
sleep(10000);
}
catch (InterruptedException ex)
{
System.out.println("thread2 interupted");
}
finally
{
System.out.println("Finished2 " this.toString());
_latch.countDown();
}
}
}
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ExecutorService workerThreadPool = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
workerThreadPool.execute(new WorkerThread(latch));
workerThreadPool.execute(new WorkerThread2(latch));
latch.await();
workerThreadPool.shutdownNow();
}
}
uj5u.com熱心網友回復:
您 - 可以 - 傳遞對 Thread 的參考,該 Thread 可以在其中發送其結果。但是您最好遵循其他答案中的建議并為此使用更好的 API :)
public static void main(//) {
ResultConsumer r = new ResultConsumer();
... create and start worker threads
}
public class WorkerThread implements Runnable {
public WorkerThread ( ResultConsumer r ) {
this.r=r
}
@Override
public void run() {
// some long task here, returns int value
r.sendResult(....)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/371841.html
上一篇:C 中執行緒分離的隨機int生成
