使用CompletableFuture故意烧掉堆栈没有产生堆栈溢出?

时间:2016-04-26 14:00:34

标签: java completable-future

我试图看到有意使用CompletableFuture导致堆栈溢出的行为,但是发现了,它导致了成功,我的递归循环刚刚停止并退出并且junit测试通过了。这真的不是我想要的行为。我想要一个快速失败的行为,所以我知道修复我的代码。

public override async Task Invoke(IOwinContext context)
{
    var path = context.Request.Path;

    var stream = context.Response.Body;
    var buffer = new MemoryStream();
    context.Response.Body = buffer;

    await Next.Invoke(context);

    var reqStream = new StreamReader(context.Request.Body);
    reqStream.BaseStream.Position = 0;
    var data = reqStream.ReadToEnd();

    if (path.Equals(new PathString("/token"),StringComparison.CurrentCultureIgnoreCase))
    {
        buffer.Seek(0, SeekOrigin.Begin);
        var reader = new StreamReader(buffer);
        var responseBody = await reader.ReadToEndAsync();            
        //check if the response body contains access token if so then do your processing
    }

    buffer.Seek(0, SeekOrigin.Begin);
    await buffer.CopyToAsync(stream);
}

我尝试在1455左右的eclipse中进行调试,但eclipse冻结并且无法加载堆栈跟踪,所以我找不到这种行为背后的原因。

所以我的问题很简单

  1. 我的代码是不正确的?
  2. CompletableFuture如何成功退出(或者可能不是在哪种情况下我的junit测试用例如何通过)。
  3. 也许操作系统很重要......我在Mac上。我之前拥有自己的本土承诺,而且那些成功地成功了。

1 个答案:

答案 0 :(得分:1)

thenAccept需要Consumer并返回CompletableFuture<Void>。如果消费者正常返回,则无效的未来将以null结束。如果消费者抛出异常,则异常完成该异常的未来。

如果你想抓住StackOverflowException,你需要从返回的未来中获取它。有很多方法可以做到这一点。例如:

future.thenAccept(p -> recurse(p+1)).join();

future.thenAccept(p -> recurse(p+1))
      .exceptionally(e -> {
          e.printStackTrace();
          return null;
      });