停止提交给ExecutorService的Runnable

时间:2012-12-18 09:11:55

标签: java executorservice

我已经在我的Java应用程序中实现了订阅。添加新订户时,应用程序会创建新任务(实现Runnable的类将在单独的线程中运行)并将其添加到ExecutorService,如:

public void Subscribe()
{
    es_.execute(new Subscriber(this, queueName, handler));
}

//...

private ExecutorService es_;

应用程序可以根据需要注册多个订阅者。现在我希望实现类似Unsubscribe的功能,以便每个订阅者都能够停止消息流。在这里,我需要一种方法来阻止ExecutorService中运行的任务之一。但我不知道如何做到这一点。

ExecutorService.shutdown()及其变体不适合我:它们会终止所有任务,我只想终止其中一项。我正在寻找解决方案。尽可能简单。感谢。

2 个答案:

答案 0 :(得分:10)

您可以使用ExecutorService#submit代替execute并使用返回的Future对象尝试使用Future#cancel取消任务

示例(假设SubscriberRunnable):

Future<?> future = es_.submit(new Subscriber(this, queueName, handler));
...
future.cancel(true); // true to interrupt if running

评论中的重要说明:

If your task doesn't honour interrupts and it has already started, it will run to completion.

答案 1 :(得分:3)

而不是使用ExecutorService.execute(Runnable)尝试使用Future<?> submit(Runnable)。此方法将Runnable提交到池中以供执行,它将返回Future个对象。通过这样做,您将获得对所有订户线程的引用。

要停止特定线程,请使用futureObj.cancel(true)。这将中断正在运行的线程,抛出InterruptedException。订阅者线程应该以这种方式进行编码,以便在此异常的情况下停止处理(例如,对于整个方法,使用包装器try / catch块的Thread.sleep(millis))。

您可以在官方API上找到更多信息: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html