Java 如何从ScheduledThreadPoolExecutor取消挂起的项?
我有一个任务,它要求我安排任务,并在某个事件发生时将其删除。我使用ScheduledThreadPoolExecutor来调度任务,这非常简单。但是,我找到了两种方法来取消挂起的项目,它们看起来都有点奇怪 我很好奇他们中是否有人达到了生产质量。如果两者都不是,那么你有什么建议 以下是我所做工作的概要:Java 如何从ScheduledThreadPoolExecutor取消挂起的项?,java,multithreading,executors,Java,Multithreading,Executors,我有一个任务,它要求我安排任务,并在某个事件发生时将其删除。我使用ScheduledThreadPoolExecutor来调度任务,这非常简单。但是,我找到了两种方法来取消挂起的项目,它们看起来都有点奇怪 我很好奇他们中是否有人达到了生产质量。如果两者都不是,那么你有什么建议 以下是我所做工作的概要: private final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1); public
private final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);
public void doStuff() {
//...
scheduler.schedule(new Runnable() {/*...*/}, 10, TimeUnit.MILISECONDS)
}
public void actOnEvent() {
cancelPendingItems();
doMoreStuff();
}
public void cancelPendnigItems() {
// TODO implement me
}
这是候选人1:
public void cancelPendingItems() {
scheduler.getQueue().clear();
}
这是候选人2:
public void cancelPendingItems() {
for (Runnable task : scheduler.getQueue()) {
scheduler.remove(task);
}
}
在我看来,这两种方法都像是黑客攻击,因为它们依赖于ScheduledThreadPoolExecutor.queue属性,而ScheduledExecutor接口中没有指定该属性。我有点担心我可能会违反ScheduledThreadPoolExecutor的不变量,我会太晚检测到它
那么,这些代码片段是否将实现我希望它们实现的功能?有更好/更干净的方法吗?注意,返回一个。只需存储这些,当调用cancel方法时,使用存储的futures上的cancel
方法来取消它们未来的迭代。我将使用列表
:
private final List futures=。。。
公共空间{
futures.add(scheduler.schedule(new Runnable(){/*…*/},10,
时间单位(毫秒);
}
公共作废取消挂起项(){
for(未来:未来)
future.cancel(true);
期货;
}
试图取消此任务的执行。如果任务已完成、已取消或由于其他原因无法取消,则此尝试将失败。如果成功,并且调用cancel时此任务尚未启动,则此任务不应运行。如果任务已经启动,则MayInterruptFrunning参数确定执行此任务的线程是否应该中断以尝试停止任务
或者你也可以使用
尝试停止所有正在执行的任务,停止正在等待的任务的处理,并返回正在等待执行的任务的列表
除了尽最大努力尝试停止处理积极执行的任务之外,没有其他保证。此实现通过Thread.interrupt()取消任务,因此任何未能响应中断的任务都可能永远不会终止
因此,您需要处理
InterruptedException
以允许被取消的线程安全退出。谢谢!幸运的是,它符合我的实际问题,因为没有太多可能的任务,所以清理会相当快。对于资源受限的应用程序来说,这一点很重要。web应用程序应该将这些存储在哪里?是否可以将它们存储在数据库中?我提前几天安排活动,有些活动在它们到来时就不再相关了。我必须运行它们吗?或者是否有某种方法可以将未来保存在数据库中,以便我可以取消该事件?
private final List<Future> futures = ...
public void doStuff() {
futures.add(scheduler.schedule(new Runnable() {/*...*/}, 10,
TimeUnit.MILISECONDS));
}
public void cancelPendingItems() {
for(Future future: futures)
future.cancel(true);
futures.clear();
}