【问题标题】:Java Web Services with Jersey and Tomcat. ¿how to stop all the threads when the web service is stopped?带有 Jersey 和 Tomcat 的 Java Web 服务。 ¿ Web 服务停止时如何停止所有线程?
【发布时间】:2013-10-29 16:41:01
【问题描述】:

我需要一些帮助才能找到解决这个问题的方法。

我有一个在 tomcat 服务器中使用 jersey 的 java web 服务。我的 java 代码为某些任务启动了一些线程。一切正常。问题是当在tomcat服务器的管理器面板上停止webservice时,线程继续他的执行。

当用户按下tomcat服务器管理器面板上的Stop按钮时,有没有办法停止这种java jersey webservice的所有线程?

谢谢

PD:我知道 java 中的线程存在一个 interrupt() 函数,但我不知道当用户按下服务器管理器面板中的停止按钮时如何启动该函数。

【问题讨论】:

  • 即使线程正在执行某些任务,您是否想在停止 Web 服务时终止线程?
  • 这是一个设计问题。你能分享一些你的应用程序的代码吗?

标签: java web-services tomcat jersey


【解决方案1】:

您可以尝试将线程设置为守护程序模式。您可以使用 Thread 中的 setDaemon() 方法来执行此操作。当唯一运行的线程都是守护线程时,Java 虚拟机退出。您创建的线程可能是用户线程,因此 JVM 不会退出。

http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean)

我确实有没有明确执行此操作的软件,但我没有遇到此问题,因此您的线程可能不知道它们应该停止运行。您可以通过使用某种控制标志来解决此问题,让您的线程知道它们现在可以停止。使用 AtomicBoolean 可以很好地解决这个问题。如果您使用的是 Tomcat,您可以创建一个 servlet 作为您的主根来启动和控制您的线程。 Tomcat 承诺在关闭时运行您的 servlet 的 destroy() 方法,这可以正确地停止您的线程运行。这是一个基本的例子。

@WebServlet(urlPatterns = {"/checkStatus"}, loadOnStartup = 1)
public class ThreadController extends HttpServlet {

    private AtomicBoolean running = new AtomicBoolean(false);
    private Thread myThread = new Thread() {

        @Override
        public void run() {
            while (running.get()) {
                //do stuff
            }
        }

    };

@Override
public void destroy() {
    running.set(false);
    myThread.interrupt();
}

@Override
public void init() throws ServletException {
    running.set(true);
    myThread.start();
}

}

虽然在我的实现中我使用 Executors 来启动和中断我的线程,但您可以自行进一步查找。

另一种选择是使用 ScheduledExecutorService。

 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> cleanUpHandle;


@Override
public void init() {
    cleanUpHandle = scheduler.scheduleAtFixedRate(cleanUp, 60, 60, TimeUnit.SECONDS);
}

@Override
public void destroy() {
    cleanUpHandle.cancel(true);
}

在我上面的示例中,cleanUp 是一个线程实现。使用调度程序的好处是您不需要在线程的 run 方法中控制 while 循环。 run 方法只对其任务进行一次迭代并完成。

这些只是您可以尝试的几件事,正确的解决方案将基于您要完成的任务。

【讨论】:

    【解决方案2】:

    使用 Web 服务上下文侦听器 WSServletContextListener 并在您的 web.xml 中配置它,并在 contextDestroyed 方法中编写停止所有线程的逻辑。在 Tomcat Manager 中点击 Stop 会发送一个ServletContextEvent 事件到

    public void contextDestroyed(ServletContextEvent event)
    

    在这里,您可以劫持事件并杀死所有线程并释放所有资源。这是停止线程的最佳位置。您的 web.xml 应按如下方式添加侦听器。例如:

          <listener>
    //Fully qualified listener class name implementing javax.servlet.ServletContextListener
           <listener-class>XXX.XXX.XXX.YourListenerClass</listener-class>
         </listener>
    

    希望这能给你一个想法!

    【讨论】:

    • 这可以与 jersey java webservice 一起使用吗?我没有任何 servlet 实现。我正在尝试查找有关如何将其添加到我的球衣网络服务的任何文档,但目前我找不到它
    • 我很久以前在 JAX-WS 中使用过这个 WSServletContextListener。您可以使用任何其他可以沿泽西岛操作的侦听器,这就是我的观点。例如,在 javax.servlet 中使用 ServletContextListener 并将其添加到您的 web.xml
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多