简体   繁体   English

使用 future 和 completableFuture 中断读取方法

[英]Interrupting read method with future and completableFuture

While solving the task, I've noticed a behavior I can not explain.在解决任务时,我注意到一个我无法解释的行为。

My task was to read from InputStream and interrupt that reading after a timeout.我的任务是从 InputStream 读取并在超时后中断读取。 Even though lots of people say blocking read can not be interrupted, I've achieved that goal using CompletableFuture尽管很多人说阻塞读取不能被中断,但我已经使用CompletableFuture实现了这个目标

public void startReader() {
   CompletableFuture<Void> future = CompletableFuture.runAsync(() -> doRead(System.in));
   future.get(5, TimeUnit.SECONDS);
}

private void doRead(InputStream in) {
   try {
      new BufferedReader(new InputStreamReader(in)).readLine();
   } catch (IOException e) {
      e.printStackTrace();
   }
}

But when I implement the same using Future , I can see TimeoutException been thrown into JVM, but I still can see that reading thread was not terminated and still running .但是当我使用Future实现相同时,我可以看到TimeoutException被抛出到 JVM 中,但我仍然可以看到读取线程没有终止并且仍在运行

public void startReader() throws ExecutionException, InterruptedException, TimeoutException {
   Future<?> future = Executors.newSingleThreadExecutor().submit(() -> doRead(System.in));
   future.get(5, TimeUnit.SECONDS);
}

private void doRead(InputStream in) {
   try {
      new BufferedReader(new InputStreamReader(in)).readLine();
   } catch (IOException e) {
      e.printStackTrace();
   }
}

Why there is such a difference?为什么会有这样的差异? I believe CompletableFuture does not make any magic我相信CompletableFuture不会产生任何魔法

Neither of your code snippets will stop the "reading" thread when you reached the future.get(5, TimeUnit.SECONDS);当您到达future.get(5, TimeUnit.SECONDS);时,您的代码片段都不会停止“阅读”线程future.get(5, TimeUnit.SECONDS); . . They will continue waiting for your input from System.in .他们将继续等待您来自System.in的输入。 If you want to stop it you should send an interrupt to that thread and hope the thread react on it.如果您想停止它,您应该向该线程发送一个中断并希望该线程对其做出反应。 Or you can force kill the thread, obviously.或者你可以强制终止线程,显然。

However, the CompletableFuture.runAsync() and Executors.newSingleThreadExecutor() calls use different threads, specially using differentdaemon flags (see What is a daemon thread in Java? ).但是, CompletableFuture.runAsync()Executors.newSingleThreadExecutor()调用使用不同的线程,特别是使用不同的守护进程标志(请参阅Java 中的守护进程线程是什么? )。 When you place a System.out.println(Thread.currentThread().isDaemon());当你放置一个System.out.println(Thread.currentThread().isDaemon()); inside your doRead() method you will see that CompletableFuture.runAsync uses a daemon thread (so it doesn't block the JVM from terminating) where Executors.newSingleThreadExecutor() does not (and keeps the JVM alive).在您的doRead()方法中,您将看到CompletableFuture.runAsync使用守护线程(因此它不会阻止 JVM 终止),而Executors.newSingleThreadExecutor()没有(并保持 JVM 处于活动状态)。

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

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