繁体   English   中英

带有Jersey和Tomcat的Java Web Services。 ¿当Web服务停止时如何停止所有线程?

[英]Java Web Services with Jersey and Tomcat. ¿how to stop all the threads when the web service is stopped?

我需要某种帮助,以了解解决此问题的方法。

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

当用户按下tomcat服务器管理器面板上的“停止”按钮时,是否存在一种停止此类java jersey webservice的所有线程的方法?

谢谢

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

您可以尝试将线程设置为守护进程模式。 您可以在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是一个Thread实现。 使用调度程序的好处是,您不需要在线程的run方法中进行while循环的控件。 run方法仅执行其任务的一个迭代并完成。

这些只是您可以尝试的几件事,正确的解决方案将基于您要实现的目标。

使用Web服务上下文侦听器WSServletContextListener并在web.xml对其进行配置,并编写逻辑以在contextDestroyed方法中停止所有线程。 在Tomcat Manager中单击“停止”会将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>

希望这能给您一个想法!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM