【问题标题】:ScheduledExecutorService shutdown not working with bufferedreader?ScheduledExecutorService 关闭不适用于缓冲阅读器?
【发布时间】:2016-07-31 10:41:31
【问题描述】:

我正在使用 Java 8。我有一个线程需要在特定时间开始并在特定时间结束。我正在使用ScheduledExecutorService 来完成这项工作:

我有两个线程,一个是“worker”,另一个是“stopworker”。 Worker 类包含我需要在特定时间运行的实际代码,“stopworker”线程只是关闭调度程序。

 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
 scheduler.schedule(worker, startSeconds, TimeUnit.SECONDS);
 scheduler.schedule(stopWorker, endSeconds, TimeUnit.SECONDS);

我的Worker 班级:

class Worker implements Runnable {
       @Override
       public void run() {
           try {
           // HTTP GET method to call and REST API and get Streaming
           // data back, it will keep alive as long as possible and
           // gets lots of data back
           ...
           BufferedReader reader = new BufferedReader(
                   new InputStreamReader(response.getStream()));
           // deal with the data   
           ...
           } catch (IOException e) {

           } finally {
                   reader.close();
           }
       }
}

我的StopWorker班级:

class StopWorker implements Runnable {
      @Override
      public void run() {
           try {
              scheduler.shutdownNow();
           } catch (Exception e) {
              e.printStackTrace();
           }
      }
}

我的代码可以在我想要的时间启动,但是它没有正确关闭。我稍微修改了这段代码,发现这是因为我使用了BufferedReader 类。

如果我将“worker”线程替换为一个简单的线程睡眠语句并且我的“stopworker”工作!这就是为什么我认为 I/O 部分可能会阻止我的关机。

我关闭线程的唯一方法是将我的BufferedReader 变量设为全局变量并在StopWorker 类中手动关闭它。但是,代码会很丑陋,并且会在代码中抛出IOException

我的猜测是shutdownNow 函数仍在等待 I/O 先完成,对吗?有没有优雅的解决这个问题的好方法?或者有没有更好的方法让线程在特定时间开始并在特定时间结束?

【问题讨论】:

  • 您在线程实现中是否正确关闭了BufferedReader reader?考虑将其包装到 try-with-resources 块中
  • 解决的方法是关闭线程阻塞的资源。工作人员应该期望处理 IOExceptions。
  • 是的,我已经在我的代码中尝试 catch finally 块,抱歉我忘记将它添加到帖子中,我已经编辑了。如何关闭正在阻塞的线程?我在哪里可以添加该代码?

标签: java multithreading executorservice threadpoolexecutor scheduledexecutorservice


【解决方案1】:

schedule() 返回一个ScheduledFuture,它有一个boolean cancel(boolean mayInterruptIfRunning) 方法。如果输入流可以通过线程中断关闭,则只需使用 true 调用它。

如果流不可中断,则需要明确关闭它。

【讨论】:

    【解决方案2】:

    在阅读了您的所有建议后,我已经弄清楚了。感谢您的帮助,尤其是对 8472 的帮助。 我已更改以下内容: 1) 将 ScheduledExecutorService 更改为 ScheduledThreadPoolExecutor。 由于某些原因,ScheduledFuture 取消不适用于我的代码中的 ScheduledExecutorService,我不知道为什么。 2) 取消课程时手动关闭BufferedReader。

    希望这能帮助遇到类似问题的人。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2012-03-11
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      相关资源
      最近更新 更多