Trouble stopping a tomcat server that is running a web application with a while (true) loop

后端 未结 2 1113
孤街浪徒
孤街浪徒 2021-01-24 03:47

I\'m developing a web application to be deployed onto Tomcat. When Tomcat is started, I use a servlet (in web.xml) to call a Java class:


    <         


        
相关标签:
2条回答
  • 2021-01-24 04:43

    I have some suggestions, but they require that you modify your architecture a bit in order to more nicely play with your container environment.

    Servlet containers support "listeners" that can get notification of various events. Specifically, one of them is the ServletContextListener which gets notified when the context (aka. webapp) is being brought into service (via the contextInitialized method) and when it is being brought out of service (via the contextDestroyed method).

    My recommendation would be to do the following:

    1. Change your Consumer class's constructor so that it does not automatically call consume(); instead, add a public method like consumeOnce and don't use a loop at that level at all
    2. Write a ServletContextListener that has a Consumer and a Thread reference as members as well as a volatile boolean stop flag; in contextInitialized it should create a new Consumer object, then launch a new (daemon) thread that:
      • Calls Consumer.consumeOnce
      • Calls Thread.sleep for an appropriate amount of time
      • Loops over the previous 2 steps until the stop flag is true
    3. Have your ServletContextListener's contextDestroyed method set the stop flag to true and call Thread.interrupt on the running thread.

    I'm sure I'm missing some exact details, but that's the general idea. When Tomcat shuts down, your code will be notified of the shutdown and you can cleanly terminate your own looping-thread. You may need to provide a way for the Consumer to abort an attempt to consume whatever it consumes (e.g. stop waiting to pull an object from an empty queue) if it doesn't abort when it gets a Thread.interrupt signal. (For instance if you use an Object.wait() in order to wait for a monitor notification, then you'll want to change that so it uses a wait with a timeout so that you won't block forever).

    0 讨论(0)
  • 2021-01-24 04:48

    You have to place the code with the loop in a different thread and start the thread from your consumer.

    private void consume() {
      Thread x = new Thread(new Runnable() {
        @Override
        public void run() {
          while(true) {
          ....
          }
       });
       x.start();
    }
    
    0 讨论(0)
提交回复
热议问题