簡體   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