java 如何立即强制终止 ThreadPoolExecutor 中的所有工作线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12821849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force terminate all workers in ThreadPoolExecutor immediately
提问by deadlock
I have a number of tasks inside a TheadPoolExecutor
. I have a stop button on my interface that should terminate all the threads inside ThreadPoolExecutor
immediately. I am looking for a way to do it. (without shutDown()
or shutDownNow()
).
我在一个TheadPoolExecutor
. 我的界面上有一个停止按钮,应该ThreadPoolExecutor
立即终止里面的所有线程。我正在寻找一种方法来做到这一点。(没有shutDown()
或shutDownNow()
)。
Thanks
谢谢
回答by Peter Lawrey
You cannot safely kill threads immediately. You tasks should instead honour interrupts and stop when interrupted. If you use ThreadPoolExecutor.shutdownNow()
, all the running tasks will be interrupted.
您不能立即安全地终止线程。你的任务应该尊重中断并在被中断时停止。如果使用ThreadPoolExecutor.shutdownNow()
,所有正在运行的任务都会被中断。
The only alternative is to the threads in a separate process is issue a signal to kill the process.
唯一的替代方法是向单独进程中的线程发出信号以终止该进程。
回答by Dani C.
The shutdown()
will only make the ThreadPoolExecutor
to reject all new submited tasks, and remove from the queue (if the ThreadPool
is an unbounded queue executor) the pending tasks.
The shutdownNow()
will do exactly the same, and also will call to the interrupt()
method of the Thread
. So, in your run()
method, you should handle it properly:
将shutdown()
只会使ThreadPoolExecutor
拒绝所有新submited任务,并从队列中删除(如果ThreadPool
是无界队列执行人)的尚未完成的任务。该shutdownNow()
会做同样的,也将调用该interrupt()
方法Thread
。因此,在您的run()
方法中,您应该正确处理它:
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
// Handle the exception, and close resources.
}
回答by Chetan Sharma
Old question but I think you can extend ThreadPoolExecutor to capture running Thread reference in beforeExecute(). When shutdownNow() would be called you can stop() all running Threads. Although I would strongly encourage relying on isInterrupted() in your tasks.
老问题,但我认为您可以扩展 ThreadPoolExecutor 以在 beforeExecute() 中捕获正在运行的线程引用。当 shutdownNow() 被调用时,你可以 stop() 所有正在运行的线程。尽管我强烈鼓励在您的任务中依赖 isInterrupted()。
Sample code ->
示例代码 ->
public class KillableThreadPoolExecutor extends ThreadPoolExecutor {
private final Map<Runnable, Thread> executingThreads;
public KillableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, String threadNamePrefix) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, new YoungMemorySafeLinkedBlockingQueue<Runnable>(), ThreadFactories.create(threadNamePrefix));
executingThreads = new HashMap<>(maximumPoolSize);
}
@Override
protected synchronized void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
executingThreads.put(r, t);
}
@Override
protected synchronized void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if(executingThreads.containsKey(r)) {
executingThreads.remove(r);
}
}
@Override
public synchronized List<Runnable> shutdownNow() {
List<Runnable> runnables = super.shutdownNow();
for(Thread t : executingThreads.values()) {
t.stop();
}
return runnables;
}
}
回答by Ravindra babu
ThreadPoolExecutor
is an ExecutorService
. You can't stop all threads in ExecutorService
either with shutdown()
or shutdownNow()
methods. You have to call shutdown(), awaitTermination()
and shutdownNow()
methods in a sequence for graceful shutdown as quoted by oracle documentation page
ThreadPoolExecutor
是一个ExecutorService
。您不能在ExecutorService
withshutdown()
或shutdownNow()
methods 中停止所有线程。您必须按顺序调用shutdown(), awaitTermination()
和shutdownNow()
方法才能正常关闭,如 oracle 文档页面所述
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Other options:
其他选项:
invokeAll()
CountDownLatch
- Iterate through all
Future.get()
for allCallable
tasks to achieve the same purpose.
invokeAll()
CountDownLatch
- 迭代通过所有
Future.get()
的所有Callable
的任务来达到同样的目的。
回答by posdef
If you can use Callable
s instead of Runnable
s in your threads you could try and call someTask.cancel()
to get rid of the running tasks at the time of shutdownNow()
call.
如果您可以在线程中使用Callable
s 而不是Runnable
s ,则可以尝试调用someTask.cancel()
以在调用时摆脱正在运行的任务shutdownNow()
。
Note that I have not tried this, so I can not guarantee it would work like you would like to, but judging from the javadoc description it's worth a try.
请注意,我还没有尝试过这个,所以我不能保证它会像你想要的那样工作,但从 javadoc 描述来看,它值得一试。