Java 当tomcat关闭时,如何关闭Springbean中的ThreadPoolExecutor?
我在Springbean中创建了一个threadpoolexecutor,所以我需要在tomcat关闭时关闭这个执行器Java 当tomcat关闭时,如何关闭Springbean中的ThreadPoolExecutor?,java,spring,javabeans,shutdown,Java,Spring,Javabeans,Shutdown,我在Springbean中创建了一个threadpoolexecutor,所以我需要在tomcat关闭时关闭这个执行器 public class PersistBO implements InitializingBean { private ThreadPoolExecutor executer; public void shutdownExecutor() { executer.shutdown(); } @Override public void afterPrope
public class PersistBO implements InitializingBean {
private ThreadPoolExecutor executer;
public void shutdownExecutor() {
executer.shutdown();
}
@Override
public void afterPropertiesSet() throws Exception {
taskQueue = new LinkedBlockingQueue<Runnable>(queueLength);
executer = new ThreadPoolExecutor(minThread, maxThread, threadKeepAliveTime,
TimeUnit.SECONDS, taskQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
}
public类PersistBO实现初始化bean{
私有线程池执行器;
公共无效关闭执行器(){
executer.shutdown();
}
@凌驾
public void afterPropertieSet()引发异常{
taskQueue=新的LinkedBlockingQueue(queueLength);
executer=新的线程池执行器(minThread、maxThread、threadKeepAliveTime、,
TimeUnit.SECONDS,taskQueue,new ThreadPoolExecutor.DiscardOldestPolicy();
}
我在google上搜索了解决方案并得到了一个结果。那就是在java.lang.runtime中添加一个shutdownhook。但是,java文档说java.lang.runtime#shutdownhook是在最后一个非守护进程线程退出时调用的。所以它是一个死锁。SpringBean中有没有关闭executor的解决方案?使用
运行时添加一个Heinz Kabutz的e是一个非常好的教程:我想执行器的生命周期应该取决于应用程序的生命周期,而不是整个Tomcat。您可以在Tomcat仍在运行时停止应用程序,因此Runtime.shutdownHook()
不适用
由于您已经使用Spring及其InitializingBean
进行初始化,因此可以在关闭应用程序上下文时使用它执行清理:
public class PersistBO implements InitializingBean, DisposableBean {
public void destroy() {
shutdownExecutor();
}
...
}
您可以实现自己的,以便在应用程序关闭时收到通知,并从侦听器关闭池。在bean上的关闭方法上使用@Predestroy注释。这将导致spring在上下文关闭时调用此方法
检查是否有某个执行器服务在后台运行线程。您可以通过调用executor.shutdownNow()
关闭执行器
另请参见这里是如何在Springbean中启动和停止线程
@PostConstruct
public void init() {
BasicThreadFactory factory = new BasicThreadFactory.Builder()
.namingPattern("myspringbean-thread-%d").build();
executorService = Executors.newSingleThreadExecutor(factory);
executorService.execute(new Runnable() {
@Override
public void run() {
try {
// do something
System.out.println("thread started");
} catch (Exception e) {
logger.error("error: ", e);
}
}
});
executorService.shutdown();
}
@PreDestroy
public void beandestroy() {
if(executorService != null){
executorService.shutdownNow();
}
}
但是java文档说,当最后一个非守护进程线程退出时,会调用java.lang.Runtime#shutdownHook。这会是死锁吗?如果您为池提供了正确的线程工厂,那么它也可以使用deamon线程。