多线程环境中的Java回调函数

胜利者

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

在Java多线程环境中实现相同功能的最佳方法是什么?即主线程创建一个子线程并提交一个任务,然后该子线程返回需要由主线程执行的回调函数。

这可能吗?在主线程中,我可以执行wait(),在子线程中,我可以执行notify(),但是在那种情况下,主线程将等待直到子线程完成。但是在AJAX中主线程继续其操作...这就是我想要的

布鲁诺·里斯(Bruno Reis)

您可以使用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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

单独线程上的javascript回调函数

来自分类Dev

Jain SIP在多线程环境中

来自分类Dev

Python中的同步-Gevent多线程环境

来自分类Dev

Java中的多线程问题

来自分类Dev

Java中的多线程错误

来自分类Dev

在多线程环境中对代码进行排序

来自分类Dev

多线程环境中的Java Singleton类行为

来自分类Dev

多线程环境中的mkdirs()函数

来自分类Dev

了解Java中的多线程

来自分类Dev

在多线程环境中交换变量

来自分类Dev

在多线程环境中捕获信号

来自分类Dev

多线程环境中的基准测试

来自分类Dev

Ruby多线程Sql(在测试环境中)

来自分类Dev

来自多线程C ++插件的回调NodeJS Javascript函数

来自分类Dev

如何在Java多线程环境中复制ArrayList <T>?

来自分类Dev

使由函数初始化的变量可用于多线程环境中的函数

来自分类Dev

我如何从析构函数中正确取消Boost的最后期限(在多线程环境中)?

来自分类Dev

Kotlin回调函数是多线程的吗?

来自分类Dev

多线程环境中的Spring Singleton行为

来自分类Dev

线程中的回调函数

来自分类Dev

Python中的同步-Gevent多线程环境

来自分类Dev

在run()之后执行的线程中的Java回调执行

来自分类Dev

Java中的多线程

来自分类Dev

多线程环境中的Ninject拦截

来自分类Dev

在多线程环境中对代码进行排序

来自分类Dev

java swing线程回调

来自分类Dev

多线程环境中的所有静态方法和私有构造函数模式

来自分类Dev

多线程环境中的Java CRC32计算

来自分类Dev

如何为 async/await 包装多线程回调?