如何调试CompletableStage死锁?

时间:2018-05-02 02:14:18

标签: java debugging asynchronous completable-future

我最近遇到的最困难的调试问题是异步操作之间的死锁。例如,给定两个CompletionStage链,其中第一个链调用依赖于第二个链完成的方法,第二个链调用依赖于第一个链完成的方法。它在现实生活中并不明显,因为依赖性往往被隐藏,有时死锁涉及三方以上。

部分问题在于无法找出CompletableStage正在等待的内容。这是因为操作引用CompletableStage,而不是相反。

现在大多数调试器提供了一定程度的死锁检测,但这仅适用于线程。 如何在CompletableStage链之间调试死锁?

1 个答案:

答案 0 :(得分:0)

我最终做了以下事情:

  • 在每个javascript if class x contains z get link of class y 链的末尾,安排一个在超时后被触发的事件:

    CompletionStage
  • 如果舞台按预期完成,请使用Set<Object> knownDeadlocks = ConcurrentHashMap.newKeySet(); // ... Future<?> deadlockListener = scope.getScheduler().schedule(() -> { if (knownDeadlocks.add(Throwables.getStackTraceAsString(context))) log.warn("Possible deadlock", context); }, DEADLOCK_DURATION.toMillis(), TimeUnit.MILLISECONDS); 禁用deadlockListener:

    CompletionStage.handle()
  • 为了完整起见,您还有:

    return stage.handle((value, throwable) ->
    {
        // WARNING: By design, CompletionStage.whenComplete() suppresses any exceptions thrown by its argument, so we use handle() instead.
        deadlockListener.cancel(false);
        if (throwable == null)
            return value;
        return rethrowException(throwable);
    });