繁体   English   中英

CompletableFuture显示不一致的线程行为

[英]CompletableFuture showing inconsistent threading behavior

CompletableFuture的文档为异步执行指定了以下行为:

所有没有显式Executor参数的异步方法都是使用ForkJoinPool#commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的Thread来运行每个任务)。 为了简化监视,调试和跟踪,所有生成的异步任务都是标记接口AsynchronousCompletionTask的实例。

但是,同步(或至少是非异步)方法的行为仍然不清楚。 在大多数情况下,代码使用原始线程执行,如下所示:

Thread thread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
        // Should run on the common pool - working as expected
        assert thread != Thread.currentThread();
}).thenRun(() -> {
        // Returns to running on the thread that launched.. sometimes?
        assert thread == Thread.currentThread();
}).join();

但是,重复此测试会产生不一致的结果,因为第二个代码块有时会使用公共池。 在这种情况下的预期行为是什么?

看着在OpenJDK执行CompletableFuture后在这里 ,它闻起来像你遇到一种竞争状态。 假设我们正在执行类似runAsync(a).thenRun(b) 如果a以前在公共池线程完成执行thenRun(b)被称为当前线程上,然后b立即在当前线程上运行一次thenRun(b)终于被调用。 在另一方面,如果thenRun(b)之前被调用a其他线程上完成,那么b是相同的线程上运行作为a曾经a终于完成。

有点像这样:

class CompletableFuture:
  function runAsync(a):
    function c():
      run a
      for each b in the handler stack:
        run b
    run c on a different thread
    return future representing c
  function thenRun(b):
    if c is done:
      run b
    else:
      put b in c's handler stack

显然, b在运行c的线程,如果thenRun之前被调用a结束。 否则, b在当前线程中运行。

如果要在哪个线程运行什么方面获得更一致的行为,则应尝试使用CompletableFuture#thenRunAsync ,以确保处理程序在某些特定的执行程序池中执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM