问题
When using the ExecutorService
returned by Executors.newSingleThreadExecutor()
, how do I interrupt it?
回答1:
In order to do this, you need to submit() a task to an ExecutorService
, rather than calling execute()
. When you do this, a Future
is returned that can be used to manipulate the scheduled task. In particular, you can call cancel(true) on the associated Future
to interrupt a task that is currently executing (or skip execution altogether if the task hasn't started running yet).
By the way, the object returned by Executors.newSingleThreadExecutor() is actually an ExecutorService
.
回答2:
Another way to interrupt the executor's internally managed thread(s) is to call the shutdownNow(..)
method on your ExecutorService
. Note, however, that as opposed to @erickson's solution, this will result in the whole ThreadPoolExecutor
becoming unfit for further use.
I find this approach particularly useful in cases where the ExecutorService
is no longer needed and keeping tabs on the Future
instances is otherwise unnecessary (a prime example of this being the exit(..)
method of your application).
Relevant information from the ExecutorService#shutdownNow(..)
javadocs:
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.
回答3:
One proper way could be customizing/injecting the ThreadFactory for the executorservice and from within the thread factory, you got the handle of the thread created, then you can schedule some task to interrupt the thread being interested.
Demo code part for the overwrited method "newThread" in ThreadFactory:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
},
5,
TimeUnit.SECONDS);
return thread;
}
}
Then you can use below to construct your executorservice instance:
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
Then after 5 seconds, an interrupt signal will be sent to the threads in executorservice.
来源:https://stackoverflow.com/questions/9280846/how-to-interrupt-executorservices-threads