如何在tomcat关闭时关闭spring bean中的ThreadPoolExecutor?

发布于 2024-12-29 17:30:27 字数 718 浏览 8 评论 0原文

我在spring bean中创建了一个threadpoolexecutor,所以我需要在tomcat关闭时关闭这个执行器。

     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());
}

我在谷歌上搜索了解决方案并得到了结果。也就是给java.lang.runtime添加一个shutdownhook。然而,java 文档说 java.lang.Runtime#shutdownHook 在最后一个非守护线程退出时被调用。所以这是一个死锁。 spring bean 有没有关闭执行器的解决方案?

I create a threadpoolexecutor in a spring bean, so I need to shutdown this executor when tomcat is shutdown.

     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());
}

I have searched solution on google and get a result. That is to add a shutdownhook to java.lang.runtime. However, the java docs says java.lang.Runtime#shutdownHook is called when the last non-daemon thread exits. So it is a dead lock. Is there any solution to shutdown executor in spring bean?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

酒与心事 2025-01-05 17:30:27

我想执行器的生命周期应该取决于应用程序的生命周期,而不是整个 Tomcat。您可以在 Tomcat 仍在运行时停止应用程序,因此 Runtime.shutdownHook() 不适用。

由于您已经使用 Spring 及其 InitializingBean 进行初始化,因此可以使用 DispasableBean 在应用程序上下文关闭时执行清理:

public class PersistBO implements InitializingBean, DisposableBean { 
    public void destroy() {
        shutdownExecutor();
    }
    ...
}

I guess lifecycle of the executor should depend on lifecycle of your application, not Tomcat as a whole. You can stop your application while Tomcat is still running, therefore Runtime.shutdownHook() is not applicable.

Since you already use Spring and its InitializingBean for initialization, you can use DispasableBean to perform cleanup when application context is being closed:

public class PersistBO implements InitializingBean, DisposableBean { 
    public void destroy() {
        shutdownExecutor();
    }
    ...
}
潇烟暮雨 2025-01-05 17:30:27

使用 Runtime 添加 关闭挂钩。这是 Heinz Kabutz 编写的非常好的教程: http://www.roseindia.net/javatutorials/挂钩%20_into_the_shutdown_call.shtml

Use the Runtime to add a shutdown hook. Here's a very good tutorial by Heinz Kabutz: http://www.roseindia.net/javatutorials/hooking%20_into_the_shutdown_call.shtml

懷念過去 2025-01-05 17:30:27

您可以实现自己的 javax.servlet.ServletContextListener 来当您的应用程序关闭时收到通知并从侦听器关闭池。

You can implement your own javax.servlet.ServletContextListener to be notified when your application is being shutdown and shutdown the pool from the listener.

装纯掩盖桑 2025-01-05 17:30:27

在 bean 的关闭方法上使用 @Predestroy 注释。这将导致 spring 在上下文关闭时调用此方法

检查是否有某个执行器服务有一个线程在后台运行。您可以通过调用 executor.shutdownNow() 来关闭执行程序。

另请参阅 http://taranmeet.com/jvm-not-关闭 spring-context-close/

Use the @Predestroy annotation on your shutdown method on the bean. this will result in spring calling this method when context is shutting down

Check if there is some executor service has a thread running in background. you can shutdown an executor by calling executor.shutdownNow().

also see http://taranmeet.com/jvm-not-shutting-down-on-spring-context-close/

ㄖ落Θ余辉 2025-01-05 17:30:27

以下是如何在 Spring bean 中启动和停止线程。

    @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();
  }
 }

Here is how to start and stop a thread in Spring bean.

    @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();
  }
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文