我使用Callable
执行了ExecutorService
个对象。
如何从此可调用项返回中间结果?
我知道Swing有javax.swing.SwingWorker#publish(results)
但我不使用Swing。
答案 0 :(得分:2)
有几种方法可以做到这一点。你可以用回调来做,或者你可以用队列来做。
以下是使用回调执行此操作的示例:
public static interface Callback<T> {
public void on(T event);
}
然后,回调的实现与您正在进行的事件有关:
final Callback<String> callback = new Callback<String>() {
public void on(String event) {
System.out.println(event);
}
};
现在您可以在池中使用回调:
Future<String> submit = pool.submit(new Callable<String>() {
public String call() throws Exception {
for(int i = 0; i < 10; i++) {
callback.on("process " + i);
}
return "done";
}
});
答案 1 :(得分:1)
目前尚不清楚“临时结果”究竟是什么。并发包中使用的接口根本不定义它,但假设方法类似于或多或少的纯函数。
因此,改为:
interim = compute something
finalresult = compute something else
做这样的事情:
interim = compute something
final1 = new Pair( interim, fork(new Future() { compute something else }) )
(Pseudocode,想传达这个想法,不是可编译的代码)
编辑这个想法是:不是运行单个单片计算块(碰巧达到一些“临时结果”可用的状态)而是将其分解,以便第一个任务返回前“临时”结果,并且同时,分叉计算最终结果的第二个任务。当然,必须将此任务的句柄传递给调用者,以便最终获得最终结果。通常,这是通过Future接口完成的。
答案 2 :(得分:1)
您可以将AtomicInteger传递给您的类(执行程序将提交的那个),在该类中增加它的值,并从调用线程中检查它&# 39; s值
这样的事情:
public class LongComputation {
private AtomicInteger progress = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException,
ExecutionException {
AtomicInteger progress = new AtomicInteger(0);
LongComputation computation = new LongComputation(progress);
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> result = executor.submit(() -> computation.compute());
executor.shutdown();
while (!result.isDone()) {
System.out.printf("Progress...%d%%%n", progress.intValue());
TimeUnit.MILLISECONDS.sleep(100);
}
System.out.printf("Result=%d%n", result.get());
}
public LongComputation(AtomicInteger progress) {
this.progress = progress;
}
public int compute() throws InterruptedException {
for (int i = 0; i < 100; i++) {
TimeUnit.MILLISECONDS.sleep(100);
progress.incrementAndGet();
}
return 1_000_000;
}
}
答案 3 :(得分:0)
您要找的是java.util.concurrent.Future。
Future表示异步计算的结果。方法 用于检查计算是否完成,等待它 完成,并检索计算结果。结果 只能在计算时使用方法get检索 完成,必要时阻止,直到准备就绪。取消是 由取消方法执行。提供了其他方法 确定任务是否正常完成或已取消。一旦 计算完成后,计算无法取消。如果你 我希望使用Future来取消可取性,但不是 提供可用的结果,您可以声明Future表单的类型 并且由于底层任务而返回null。
答案 4 :(得分:0)
如果要将推送中间结果发布,则必须使用Observer
/ Observerable
之类的内容来推广自己的API。更简单的方法是通过一些自定义方法轮询当前状态。