如何在没有特定顺序的情况下管理多个可调用线程结果?
How can I manage multiple callable threads result without a specific order?
基本上是这样的:
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Boolean> futureFoo = service.submit(myFooTask);
Future<Boolean> futureBar = service.submit(myBarTask);
int resultFoo;
boolean resultBar;
resultFoo = futureFoo.get();
resultBar = futureBar.get();
我想做一个事件来独立管理我得到的第一个结果,而不是等待 futureFoo
先完成。
您可以使用 CompletionService。可调用对象的结果放入队列中,您可以在任务完成后立即获取任务结果。
在这种情况下,如果 Bar 较早完成,则无需等待 Foo 的结果。
例如:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletionServiceExample {
private static Logger LOGGER = Logger.getLogger("CompletionServiceExample");
public static void main(String[] args) throws InterruptedException {
CompletionServiceExample completionServiceExample = new CompletionServiceExample();
completionServiceExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executorService);
completionService.submit(new Foo());
completionService.submit(new Bar());
int total_tasks = 2;
for(int i = 0; i < total_tasks; ++i) {
try {
final Future<Boolean> value = completionService.take();
System.out.println("received value: " + value.get());
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Error while processing task. ", e);
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "interrupted while waiting for result", e);
}
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Foo implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(5000);
return true;
}
}
class Bar implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(1000);
return false;
}
}
如果你想 return 不同的类型,你可以使用基数 class 并进行向下转换。例如像这样:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletionServiceExample {
private static Logger LOGGER = Logger.getLogger("CompletionServiceExample");
public static void main(String[] args) throws InterruptedException {
CompletionServiceExample completionServiceExample = new CompletionServiceExample();
completionServiceExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final CompletionService<Base> completionService = new ExecutorCompletionService<>(executorService);
completionService.submit(new FooBase());
completionService.submit(new BarBase());
int total_tasks = 2;
for (int i = 0; i < total_tasks; ++i) {
try {
final Future<Base> value = completionService.take();
Base base = value.get();
if (base instanceof FooBase) {
int myInteger = ((FooBase) base).getValue();
System.out.println("received value: " + myInteger);
}
if (base instanceof BarBase) {
boolean myBoolean = ((BarBase) base).isValue();
System.out.println("received value: " + myBoolean);
}
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Error while processing task. ", e);
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "interrupted while waiting for result", e);
}
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Base {
}
class FooBase extends Base implements Callable<Base> {
private int value;
@Override
public Base call() throws Exception {
Thread.sleep(5000);
value = 10;
return this;
}
public int getValue() {
return value;
}
}
class BarBase extends Base implements Callable<Base> {
private boolean value;
@Override
public Base call() throws Exception {
Thread.sleep(1000);
value = false;
return this;
}
public boolean isValue() {
return value;
}
}
基本上是这样的:
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Boolean> futureFoo = service.submit(myFooTask);
Future<Boolean> futureBar = service.submit(myBarTask);
int resultFoo;
boolean resultBar;
resultFoo = futureFoo.get();
resultBar = futureBar.get();
我想做一个事件来独立管理我得到的第一个结果,而不是等待 futureFoo
先完成。
您可以使用 CompletionService。可调用对象的结果放入队列中,您可以在任务完成后立即获取任务结果。
在这种情况下,如果 Bar 较早完成,则无需等待 Foo 的结果。
例如:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletionServiceExample {
private static Logger LOGGER = Logger.getLogger("CompletionServiceExample");
public static void main(String[] args) throws InterruptedException {
CompletionServiceExample completionServiceExample = new CompletionServiceExample();
completionServiceExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executorService);
completionService.submit(new Foo());
completionService.submit(new Bar());
int total_tasks = 2;
for(int i = 0; i < total_tasks; ++i) {
try {
final Future<Boolean> value = completionService.take();
System.out.println("received value: " + value.get());
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Error while processing task. ", e);
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "interrupted while waiting for result", e);
}
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Foo implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(5000);
return true;
}
}
class Bar implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(1000);
return false;
}
}
如果你想 return 不同的类型,你可以使用基数 class 并进行向下转换。例如像这样:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletionServiceExample {
private static Logger LOGGER = Logger.getLogger("CompletionServiceExample");
public static void main(String[] args) throws InterruptedException {
CompletionServiceExample completionServiceExample = new CompletionServiceExample();
completionServiceExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final CompletionService<Base> completionService = new ExecutorCompletionService<>(executorService);
completionService.submit(new FooBase());
completionService.submit(new BarBase());
int total_tasks = 2;
for (int i = 0; i < total_tasks; ++i) {
try {
final Future<Base> value = completionService.take();
Base base = value.get();
if (base instanceof FooBase) {
int myInteger = ((FooBase) base).getValue();
System.out.println("received value: " + myInteger);
}
if (base instanceof BarBase) {
boolean myBoolean = ((BarBase) base).isValue();
System.out.println("received value: " + myBoolean);
}
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Error while processing task. ", e);
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "interrupted while waiting for result", e);
}
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Base {
}
class FooBase extends Base implements Callable<Base> {
private int value;
@Override
public Base call() throws Exception {
Thread.sleep(5000);
value = 10;
return this;
}
public int getValue() {
return value;
}
}
class BarBase extends Base implements Callable<Base> {
private boolean value;
@Override
public Base call() throws Exception {
Thread.sleep(1000);
value = false;
return this;
}
public boolean isValue() {
return value;
}
}