Java 停止提交给ExecutorService的可运行文件

Java 停止提交给ExecutorService的可运行文件,java,executorservice,Java,Executorservice,我已经在Java应用程序中实现了订阅。添加新订户时,应用程序将创建新任务(实现Runnable以在单独线程中运行的类),并将其添加到ExecutorService中,如: public void Subscribe() { es_.execute(new Subscriber(this, queueName, handler)); } //... private ExecutorService es_; 应用程序可以注册任意数量的订户。现在我想实现类似于取消订阅的功能,这样每个订阅

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

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

//...

private ExecutorService es_;
应用程序可以注册任意数量的订户。现在我想实现类似于
取消订阅
的功能,这样每个订阅者都可以停止消息流。在这里,我需要一种方法来停止
ExecutorService
中运行的任务之一。但我不知道该怎么做

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

您可以使用而不是
execute
并使用返回的
Future
对象来尝试使用取消任务

示例(假设订阅服务器是可运行的):

Future-Future=es_uu.submit(新订户(this,queueName,handler));
...
future.cancel(true);//如果正在运行,则为true以中断

评论中的重要注释:


如果您的任务不接受中断并且已经启动,它将运行到完成。

而不是使用
执行器服务。执行(可运行)
尝试使用
未来提交(可运行)
。此方法将
Runnable
提交到池中执行,并返回
Future
对象。通过这样做,您将拥有对所有订阅者线程的引用

要停止特定线程,只需使用
futureObj.cancel(true)
。这将中断正在运行的线程,并抛出一个
InterruptedException
。订阅者线程的编码方式应确保在出现此异常时它将停止处理(例如整个方法的
thread.sleep(millis)
和包装器try/catch块)

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

注意:如果您的任务不接受中断,并且已经启动,它将运行到完成。@彼得拉维这是否意味着如果您的任务捕获到InterruptedException(并且没有重新启动)?@ataulm interrupt()设置一个标志。如果代码没有检查标志或调用一个有检查标志的方法,那么它就是一个标志。@PeterLawrey,我试图在(true){..}时删除对中断标志的检查,即使在调用cancel()后,它也没有完成。所以我猜如果任务不尊重中断,那么它将运行到完成的声明是错误的。它只是无限期地运行。executorService.submit没有抛出InterruptedException,因此我们无法捕获它
Future<?> future = es_.submit(new Subscriber(this, queueName, handler));
...
future.cancel(true); // true to interrupt if running