5

我正在开发一个在某些时候启动工作线程的应用程序。此线程的行为将根据用于启动它的参数而有很大差异,但以下属性列表适用:

  • 它会做一些小的 I/O 操作
  • 它将在 3rd 方库中花费少量时间
  • 它可能会为某个子任务创建一些工作线程(这些线程在他们的任务完成后不会被重用)
  • 它将花费大部分时间处理数字(不存在阻塞调用)

由于可能的持续时间较长(5 分钟到几个小时,具体取决于输入),我们希望能够中止计算。如果我们选择中止它,我们就不再关心输出,只要线程继续运行,实际上就是在浪费宝贵的资源。由于代码在我们的控制之下,建议的方法是使用中断来指示中止。

虽然网络上的大多数示例都处理循环某个方法的工作线程,但对我来说并非如此(类似的问题在这里)。这个工作线程中的阻塞调用也很少,这种情况本文建议手动检查中断标志。我的问题是:如何处理这个中断?

我看到了几个选项,但无法决定哪个是最“干净”的方法。尽管有我的实际示例,但我主要对如何处理此问题的“最佳实践”感兴趣。

  1. 抛出某种未经检查的异常:这会以一种快速简单的方式杀死线程,但它让我想起ThreadDeath了不推荐使用的方法所使用的Thread#stop()方法,以及所有相关的问题。我可以看到这种方法在拥有的代码中是可以接受的(由于已知的逻辑流程),但在库代码中却不是。
  2. 抛出某种检查异常:这将以一种快速简单的方式杀死线程,并ThreadDeath通过强制程序员处理此事件来缓解类似的问题。但是,它给代码带来了很大的负担,需要在任何地方都提到异常。并非所有东西都会抛出InterruptedException.
  3. 以“迄今为止最好的结果”或空结果退出方法。由于涉及的课程数量众多,这将是一项非常艰巨的任务。如果没有采取足够的措施,NullPointerExceptions可能会出现空结果,导致与第 1 点相同的问题。在大型代码库中几乎不可能找到这些原因。
4

2 回答 2

1

我建议您定期检查 Thread.currentThread().isInterrupted() 在您知道是否可以安全停止并停止设置的点。

您可以在检查此标志并引发自定义未检查异常或错误的方法中执行此操作。

于 2013-09-05T09:06:25.180 回答
0

使用 ExecutorService 来执行 Runnable 怎么样?查看可以指定超时的方法。例如

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();

这里Task当然实现了Runnable。

于 2013-09-05T09:12:02.647 回答