- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在玩 Java 8 可完成的 future 。我有以下代码:
CountDownLatch waitLatch = new CountDownLatch(1);
CompletableFuture<?> future = CompletableFuture.runAsync(() -> {
try {
System.out.println("Wait");
waitLatch.await(); //cancel should interrupt
System.out.println("Done");
} catch (InterruptedException e) {
System.out.println("Interrupted");
throw new RuntimeException(e);
}
});
sleep(10); //give it some time to start (ugly, but works)
future.cancel(true);
System.out.println("Cancel called");
assertTrue(future.isCancelled());
assertTrue(future.isDone());
sleep(100); //give it some time to finish
我使用 runAsync 安排执行等待闩锁的代码。接下来我取消了future,期待里面抛出一个中断的异常。但似乎线程在 await 调用中仍然被阻塞,并且即使 future 被取消(断言通过)也永远不会抛出 InterruptedException 。使用 ExecutorService 的等效代码按预期工作。这是 CompletableFuture 中的错误还是我的示例中的错误?
最佳答案
当您调用 CompletableFuture#cancel
时,您只会停止链的下游部分。上游部分,i。 e.最终将调用 complete(...)
或 completeExceptionally(...)
的东西,不会得到任何不再需要结果的信号。
那些“上游”和“下游”的东西是什么?
让我们考虑以下代码:
CompletableFuture
.supplyAsync(() -> "hello") //1
.thenApply(s -> s + " world!") //2
.thenAccept(s -> System.out.println(s)); //3
在这里,数据从上到下流动——从供应商创建,通过功能修改,到被 println
使用。特定步骤上方的部分称为上游,下方的部分称为下游。例如步骤 1 和步骤 2 是步骤 3 的上游。
这是幕后发生的事情。这并不精确,而是对正在发生的事情的一个方便的思维模型。
ForkJoinPool
内)。complete(...)
传递到下一个 CompletableFuture
下游。CompletableFuture
调用下一步 - 一个函数(第 2 步)接收上一步结果并返回将进一步传递给下游 CompletableFuture
的 complete(...)
。CompletableFuture
调用消费者 System.out.println(s)
。消费者完成后,下游CompletableFuture
会收到它的值,(Void) null
正如我们所见,此链中的每个 CompletableFuture
都必须知道下游有谁在等待将值传递给它们的 complete(...)
(或 completeExceptionally(...)
)。但是 CompletableFuture
不必知道任何关于它的上游(或上游 - 可能有多个)的信息。
因此,在第 3 步调用 cancel()
不会中止第 1 步和第 2 步,因为没有从第 3 步到第 2 步的链接。
如果您正在使用 CompletableFuture
,那么您的步骤应该足够小,因此如果执行几个额外的步骤也不会造成损害。
如果您希望将取消传播到上游,您有两种选择:
CompletableFuture
(将其命名为 cancelled
),它在每一步之后都会被检查(类似于 step.applyToEither(cancelled, Function .identity())
)关于java - 如何取消 Java 8 可完成的 future ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23320407/
是否可以使用标准输入/标准输出在 bash 中压缩/解压缩字符串? 我试过了,但显然不支持它? hey=$(echo "hello world" | gzip -cf) echo $hey # ret
我的任务是让一个企业网站适用于 IE7,它必须“足够好”,因此我禁用了任何导致问题的花哨/非必要功能。 其中之一是正在使用的搜索栏,需要进行哪些搜索,我猜测幕后某个地方有某种 JavaScript 用
我有一个执行大量处理的小程序。您可以通过按回车键打印进度。 我实现它的方法是在主线程中完成处理,同时我有一个 pthread 不断循环 getchar() 以等待输入键。 问题是当我完成处理时。发生这
我完全理解 suspendCoroutine 与 suspendCancellableCoroutine 在我的示例中的工作方式。但我想知道为什么 println("I finished") (第 1
我是 QT 的新手。目前在我的项目中我实现了 QFileDialog . 在我的用例中:每当用户选择一个文本文件时,它都会执行 functionA .但是,我发现如果在文件对话框中单击取消,funct
我有代码,仅在用户选择“另存为”时运行。为此并获取我正在使用的文件的新名称 Application.GetSaveAsFilename功能。 我遇到的问题是类型不匹配,同时检查用户是否在他没有这样做时
我的 UILocalNotification 有问题。 我正在用我的方法安排通知。 - (void) sendNewNoteLocalReminder:(NSDate *)date alrt:(NS
祝你有美好的一天 我有一个网站,其中有很多“工具提示”。这些工具提示是在将鼠标悬停在文本的特定部分上时创建的。工具提示是一个 div block ,它显示在网站上所有其他内容的顶部,并且当光标从文本移
我遇到以下问题。每隔 2 秒,程序就会进入 if 语句。在这个 if 语句中,我想要一个计时器,它会在 15 秒后给我一条消息。计时器应延迟 1 秒运行。但是当我用计时器“等待”时,if 语句将再执行
基本上我有以下代码片段, (let [task (FutureTask. fn) thr (Thread. task)] (.start thr) ;;wait for signa
取消正在进行的 ASIHttpRequest 请求的正确位置在哪里?这就是我取消的方式,但是当我 时它继续崩溃在不让请求完成的情况下从一个 View Controller 转移到另一个 View Co
我在我的 winforms 应用程序中使用 BackgroundWorker 来执行另一个类中发生的长时间运行的任务(执行数据库操作)。由于所有工作都是在另一个类中完成的,因此取消并不那么简单。我在另
我正在使用 OneSignal 向我的用户显示通知。通知工作正常,但我注意到,如果我在通知栏中“滑动”取消通知,则通知将永远保留,这是一张显示应用程序图标上的通知的图像,我想在应用程序已打开: 我看到
正在运行的 AsyncTask 的 .cancel(boolean) 方法如何工作?这是文档: Attempts to cancel execution of this task. This atte
我注意到,当我激活约束时,我会立即在该行代码处收到一条警告,指出不能同时满足约束。 我假设布局是在“UI 更新周期”之类的稍后时间点计算的,而不是每次约束都被(取消)激活。因此,在(取消)激活约束的代
这是我创建线程的方式: readFromWebThread = [[NSThread alloc] initWithTarget:self selector:@selector(loadThread:
我目前正在尝试取消与我的数据模型中的对象关联的特定 UILocalNotifications。为此,每个数据对象都有一个唯一标识符,即 NSUUID。 创建 UILocalNotification:
当我提交并单击“确定”时,它会继续,但当我按“取消”时,它仍然会提交。我尝试使用此代码,但提交和取消按钮仍然执行相同的操作。 model.saveForm = function() { var
我有一个警报弹出窗口,当发生特定操作时会出现该弹出窗口。 5 秒后,使用 setTimeout() 隐藏警报弹出窗口。 我遇到的问题是,如果我多次触发弹出窗口,有时后续的弹出窗口会出现但立即消失。我相
我有一些 javascipt (jQuery),其中单击按钮时会淡入 #myDiv,然后使用超时函数在 5 秒后再次淡出。它工作正常,但如果用户在超时内的 fadeOut 函数运行之前再次单击该按钮,
我是一名优秀的程序员,十分优秀!