ThreadPoolExecutor中的shutdown()、shutdownNow()、。。。
Java并发编程中在使⽤到ThreadPoolExecutor时,对它的三个关闭⽅法(shutdown()、shutdownNow()、awaitTermination())的异同点如下:
shutdown()
将线程池状态置为SHUTDOWN,并不会⽴即停⽌:
1. 停⽌接收外部submit的任务
2. 内部正在跑的任务和队列⾥等待的任务,会执⾏完
3. 等到第⼆步完成后,才真正停⽌
shutdownNow()
将线程池状态置为STOP。企图⽴即停⽌,事实上不⼀定:
1. 跟shutdown()⼀样,先停⽌接收外部提交的任务
2. 忽略队列⾥等待的任务
3. 尝试将正在跑的任务interrupt中断
4. 返回未执⾏的任务列表
它试图终⽌线程的⽅法是通过调⽤Thread.interrupt()⽅法来实现的,但是⼤家知道,这种⽅法的作⽤有限,如果线程中没有sleep 、wait、Condition、定时锁等应⽤, interrupt()⽅法是⽆法中断当前的线程的。所以,ShutdownNow()并不代表线程池就⼀定⽴即就能退出,它也可能必须要等待所有正在执⾏的任务都执⾏完成了才能退出。但是⼤多数时候是能⽴即退出的
awaitTermination(long timeOut, TimeUnit unit)
当前线程阻塞,直到
1. 等所有已提交的任务(包括正在跑的和队列中等待的)执⾏完
2. 或者等超时时间到
3. 或者线程被中断,抛出InterruptedException
然后返回true(shutdown请求后所有任务执⾏完毕)或fal(已超时)
shuntdown()和awaitTermination()效果差不多,⽅法执⾏之后,都要等到提交的任务全部执⾏完才停。
shutdown() 和 shutdownNow()的区别
从字⾯意思就能理解,shutdownNow()能⽴即停⽌线程池,正在跑的和正在等待的任务都停下了。这样做⽴即⽣效,但是风险也⽐较⼤;
shutdown()只是关闭了提交通道,⽤submit()是⽆效的;⽽内部该怎么跑还是怎么跑,跑完再停。
Between client threads and thread pool there is a queue of tasks. When your application shuts down, you must take care of two things: what is happening with queued tasks and how already running tasks are behaving (more on that later). Surprisingly many developers are not shutting down thread pool properly or consciously. There are two techniques: either let all queued tasks to execute (shutdown()) or drop them (shutdownNow()) - it totally depends on your u ca.
shutdown()和awaitTermination()的区别
1. shutdown()后,不能再提交新的任务进去;但是awaitTermination()后,可以继续提交。
2. awaitTermination()是阻塞的,返回结果是线程池是否已停⽌(true/fal);shutdown()不阻塞。
总结
1. 优雅的关闭,⽤shutdown()
2. 想⽴马关闭,并得到未执⾏任务列表,⽤shutdownNow()
3. 优雅的关闭,并允许关闭声明后新任务能提交,⽤awaitTermination()
ps:关闭功能【从强到弱】依次是:shuntdownNow() > shutdown() > awaitTermination()
awaitTermination并不是⽤来关闭线程池,它只是⽤来检测timeout时间后线程池是否关闭。
⼀般在调⽤shutdown()⽅法后调⽤