我使用过shutDown()
和shutDownNow()
,但这两种方法都不会立即停止所有线程。在这两者中更优选shutDownNow()
,但它等待正在运行的线程完成它的任务。在我的场景中,我有一个处理 postgres 数据库的巨大任务,我想立即关闭该线程而不等待执行完成。
立即关闭所有线程的方法是什么?
答案 0 :(得分:1)
shutdownNow: 尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。 此方法不等待主动执行任务终止。使用awaitTermination来做到这一点。
关机: 启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。如果已经关闭,调用没有其他影响。 此方法不会等待先前提交的任务完成执行。使用awaitTermination来做到这一点。
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown%28%29
或者你可以看到:
您可以使用ExecutorService,它将线程池与任务队列组合在一起。
ExecutorService service = Executors.newCachedThreadPool();
// or
ExecutorService service = Executors.newFixedThreadPool(THREADS);
// submit as many tasks as you want.
// tasks must honour interrupts to be stopped externally.
Future future = service.submit(new MyRunnable());
// to cancel an individual task
future.cancel(true);
// when finished shutdown
service.shutdown();
答案 1 :(得分:0)
停止线程的单一“干净”方法是,如果你有一些循环,要通过一些布尔变量来停止循环,比如“stopThread”,你必须处理变量。
示例:
public void run(){
for(int i = 0; i< 1000000&&(!stopThread); i ++){
// do something
} }
答案 2 :(得分:0)
我怀疑这是安全的。
根据oracle documentation
关闭执行程序服务的安全方法 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();
}
}
如果你真的想采取粗暴的方式,我会建议一个可能不是100%准确的解决方案,我不建议亲自。我想使用ExecutorService方法而不是这个粗略的解决方案。
Worker
主题中添加一个布尔值 - boolean runNow = true;
while ( runNow) { // your logic }
ThreadPoolManager
中再添加一个方法。迭代myQueue
并中断所有Runnables
。捕获中断的异常并将布尔值runNow
设为false。答案 3 :(得分:0)
根据您调用数据库的方式,您可以尝试显式取消查询。 Se related question。