gpt4 book ai didi

多线程环境下的java回调函数

转载 作者:行者123 更新时间:2023-11-29 05:41:14 25 4
gpt4 key购买 nike

在 AJAX 中,假设我异步提交请求。当 reposne 返回时,它会执行一个回调函数。

在 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 ,而不是有一个结果列表并对其进行迭代,您可以通过它的 .take() 方法从 CompletionService 本身获得您的 future ,该方法会阻塞直到计算完成,或 .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...");
}
}

关于多线程环境下的java回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17495896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com