在AJAX中,假设我异步提交请求。当回购返回时,它将执行一个回调函数。
在Java多线程环境中实现相同功能的最佳方法是什么?即主线程创建一个子线程并提交一个任务,然后该子线程返回需要由主线程执行的回调函数。
这可能吗?在主线程中,我可以执行wait(),在子线程中,我可以执行notify(),但是在那种情况下,主线程将等待直到子线程完成。但是在AJAX中主线程继续其操作...这就是我想要的
您可以使用ExecutorService
在后台执行任务,然后使用返回的方法Future
来等待结果。例如:
class Main {
private static final ExecutorService es = Executors.newCachedThreadPool();
public static void main(final String... args) throws Throwable {
List<Future<Integer>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(asyncSum(i, i*i));
}
// here, in the main thread, you can do whatever you want
// while the calculations are performed in background threads
// ...
// after the main thread finishes what it was doing, it
// can process the futures
for (final Future<Integer> result : results) {
System.out.println(result.get());
}
}
// this method launches a calculation on a worker thread and immediately
// returns a Future, which is a reference to the result of the calculation
// once it is completed
private static Future<Integer> asyncSum(final int a, final int b) {
return es.submit(new Callable<Integer>() {
@Override public Integer call() throws Exception {
return a + b;
}
});
}
}
在上面的示例中,主线程将阻塞,直到完成第一个计算,然后再打印它。然后阻塞,直到完成第二次计算,然后再打印,依此类推。
如果您希望在结果可用时(以未指定的顺序)打印结果,则可以使用CompletionService
,而不是使用结果列表并对其进行迭代,您可以通过CompletionService本身的.take()
方法来获取其期货。,会阻塞直到计算完成为止;或者.poll()
,如果存在已完成的计算则返回Future;或者如果没有完成的计算将返回null,这样您的主线程将永远不会阻塞。
以下示例使用CompletionService
。它显示了一个永不阻塞的主线程,使用后台线程进行计算并在结果可用时处理结果:
class Main {
public static void main(String[] args) throws Throwable {
final ExecutorService es = Executors.newCachedThreadPool();
final CompletionService<Integer> cs = new ExecutorCompletionService<>(es);
submitSomeCalculations(cs);
while (true) {
doMainThreadWork();
processFinishedCalculations(cs);
}
}
private static void submitSomeCalculations(final CompletionService<Integer> cs) {
for (int i = 0; i < 10; i++) {
submitAsyncSum(cs, i, i * i);
}
}
private static void submitAsyncSum(final CompletionService<Integer> cs, final int a, final int b) {
cs.submit(new Callable<Integer>() {
@Override public Integer call() throws Exception {
Thread.sleep(100 + (long) (Math.random() * 900));
return a + b;
}
});
}
private static void processFinishedCalculations(final CompletionService<Integer> cs) throws ExecutionException, InterruptedException {
while (true) {
final Future<Integer> result = cs.poll();
if (result == null) {
System.out.println("> no finished results...");
break;
} else {
System.out.println("> result available: " + result.get());
}
}
}
static void doMainThreadWork() {
System.out.println("work from main thread...");
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句