0

我需要某种帮助才能找到解决此问题的方法。

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

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

谢谢

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

4

2 回答 2

0

使用 Web 服务上下文侦听器WSServletContextListener并在您的配置它web.xml并编写逻辑以停止contextDestroyedMethod 中的所有线程。ServletContextEvent单击 Tomcat 管理器中的停止将向

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>

希望这能提供一个想法!

于 2013-10-29T17:39:06.530 回答
0

您可以尝试将线程设置为守护程序模式。您可以使用 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 方法只对其任务进行一次迭代并完成。

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

于 2013-10-29T17:23:42.307 回答