java - 检索使用 ScheduledExecutorService 计划的任务实例

标签 java concurrency lucene scheduled-tasks try-catch-finally

我有一个 ScheduledExecutorService用于 JEE 环境中的任务调度。其中一些任务在被 ScheduledExecutorService.shutdownNow() 中断时使资源保持打开状态(例如,使用像 Lucene 这样的第三方库打开文件)。

我知道线程可能不会自己停止执行:停止线程必须使用的方法是检查中断标志并停止方法执行,如果线程是阻塞的(例如 wait()、sleep()等)或者如果在可中断 channel 中执行一些 IO 操作 Thread.interrupt()将制作一个 InterruptedException上升。在这两种情况下,都必须执行 finally block 。 请参阅:http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Thread.html#interrupt%28%29 .

显然,我已经尝试在 Task 类中使用一个实现良好的 finally block 来释放资源,但在某些环境中(例如 CentOS),当线程被中断时,finally block 不会被执行。然后我在官方 Java 文档中发现了这个非常酷的注释:

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

所以,我需要的是对所有计划任务的引用,以便在强制释放资源的任务类中实现一些公共(public)方法。我可以从 ScheduledExecutorService 中检索对任务类的引用吗? ?或者您有什么很棒的想法可以更好地解决我的问题?

第一个解决方案:包裹起来!

ScheduledExecutorService 创建一个包装类并添加如下属性:

private IdentityHashMap<ScheduledFuture<?>, Runnable> taskList;

有了它,我们可以直接访问任何 Runnable 对象,或者通过 ScheduledFuture与它有关。对于包装器的实例化,我可以获得 ScheduledExecutorService来自 Executors.newScheduledThreadPool()方法并将其传递给我的包装器。

另一个解决方案:扩展它!

扩展ScheduledThreadPoolExecutor ,添加 IdentityHashMap 属性并覆盖所有计划或取消作业的方法,以在 Map 中添加/删除引用。

两种解决方案都有问题吗?

如果您的包装器或扩展类的调用者收到 SchedulerFuture<?>对象,使用 SchedulerFuture<?>.cancel() 取消作业方法是可能的,绕过你的“胶囊”。使用包装器,您可以避免传递 SchedulerFuture<?>对调用者的引用,但是对于扩展类你不能(如果你在扩展类中创建你自己的方法你会得到与包装器相同的结果,但是以一种非常困惑的方式)。

优雅的解决方案:您自己的调度程序!感谢 Kaj 指出...

  1. 扩展ScheduledThreadPoolExecutor覆盖 decorateTask()方法
  2. 装饰Runnable一个实现 ScheduledFuture界面
  3. 实现一项定制 cancel()实际上的方法 取消线程但也操纵 Runnable反对强制 资源释放。

查看我的博客 post有关详细信息和代码示例!!!

最佳答案

你有什么安排?任务是什么样的?我发现很难相信 finally block 没有被执行。我猜这是您已安排但尚未开始执行的任务正在泄漏资源(因为它们的 finally block 不会被执行)

如果 CentOS 真的没有执行那些 finally block 的话,这听起来像是一个非常糟糕的 VM 实现。在任何其他 VM 实现中都没有听说过。

您可以做的一个选择是继承 ScheduledThreadPoolExecutor 并覆盖 decorateTask 方法,以便它们用您的类,然后拦截取消调用。

关于java - 检索使用 ScheduledExecutorService 计划的任务实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6871709/

相关文章:

java - 同时启动多个线程

elasticsearch - 按字母顺序对关键字建立索引列表VS在Elasticsearch中根本不排序?

c# - 将字符串转换为 Linq lambda 表达式

java - 如何在 javax.swing.text.HtmlDocument 中为元素创建 ComponentView

java - 如何让用户猜出我的 Hangman 应用程序中的整个单词?

java - "Partial Ordering"和 Happens-before 关系 java

elasticsearch - Lucene如何索引not_analyzed字段

java - 在 libGDX 中移动对象的最佳方法是什么

java - 如何在 Java 中更快地计算 sha256?

c++ - 何时在多线程中使用 volatile?