我发现CompletableFuture::join
在未完成时似乎不间断:
// CompletableFuture::join implementation from JDK 8 sources
public T join() {
Object r;
return reportJoin((r = result) == null ? waitingGet(false) : r);
}
在上面的实现中,waitingGet(false)
将忽略工作Thread
的中断标志并继续等待。我想知道如何打断Thread
CompletableFuture::join
。
答案 0 :(得分:7)
如果您想支持中断,请不要使用module.exports = function(req, res) {
let formidable = require('formidable');
let form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
let readStream = fs.createReadStream(files.uploadedfile.path);
let ffmpeg = require('fluent-ffmpeg')
let ffmpegCmd = ffmpeg(readStream)
...
});
});
,而是使用join()
。基本上它们是相同的,除了:
get()
仅在join()
中定义,而CompletableFuture
来自接口get()
Future
包含join()
中的例外情况,而CompletionException
将其包含在get()
ExecutionException
可能会被中断,然后会抛出get()
请注意,您中断的是InterruptedException
,而不是Thread
。例如,以下代码在等待Future
:
myFuture.get()
输出:
CompletableFuture<Void> myFuture = new CompletableFuture<>();
Thread mainThread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println("Interrupting…");
mainThread.interrupt();
Thread.sleep(1000);
System.out.println("Completing");
myFuture.complete(null);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
myFuture.get();
System.out.println("Get succeeded");
} catch (Exception e) {
System.out.println("Get failed");
e.printStackTrace();
}
如果您将Interrupting…
Get failed
java.lang.InterruptedException
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at CompletableFutureInteruption.main(CompletableFutureInteruption.java:37)
…
替换为get()
,则中断确实无效。
答案 1 :(得分:2)
我终于放弃了在等待CompletableFuture::join
完成时阻塞的线程。
相反,我使用CompletableFuture::allof
来获取CompletableFuture
所有,当我所有加入的期货结束时结束。然后在工作线程中调用 all Future的get()
方法。当get()
返回时,我会通过迭代所有已加入的期货来收集我的所有结果,并在其上调用getNow
。这样的程序是可以中断的。
答案 2 :(得分:0)
我最后清楚地知道你不实际上正在寻找可中断的,但作为一种解决方法可以被例外打断如下(尽管它是join()
):
private static void testCompleteExceptionally() {
String name = "Hearen";
CompletableFuture<String> completableFuture
= CompletableFuture.supplyAsync(() -> {
delay(500L);
if (name == null) {
throw new RuntimeException("Computation error!");
}
return "Hello, " + name;
});
if (name != null) {
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
}
out.println(completableFuture.handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString()).join());
}