简体   繁体   中英

Apache Tomcat Servlet threads not finishing

I've written a servlet deployed in tomcat.

public class myServlet extends HttpServlet {
    public int NumberOfThreads = 0;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    System.out.println(NumberOfThreads);
    NumberOfThreads++;
    ....
    ..a lot of code..
    ....
    NumberOfThreads--;
    }
}

Now when I get too many requests the NumberOfThreads keeps rising and never goes down again. My problem is that there is a few tasks that have to be performed by each request before leaving.

I just don't understand why this happens. Is it that some of the threads get lost on the way? I really need each request to say properly goodbye.

Thanks

As you're speaking about this taking a long time and requests are being cancelled (in your comment): Yes, the whole doGet will be executed, even when the user cancelled the request: Request cancelling is only on HTTP level. However, when the request is cancelled, the HTTP connection might be closed, resulting in exceptions when you actually want to write to the response's output stream.

Combining the other answers already given:

  • You'll need to synchronize your modifications of the counter (see didxga's answer)
  • there's probably a better way to solve your problem (as Ravi Thapliyal states)
  • use try{ ... } finally { ... } to ensure you actually decrease the counter
  • make your code more maintainable by moving it out of the servlet into a proper, non-UI, class

Pseudo code:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        synchronized(this){NumberOfThreads++;}
        doSomething();
    } finally {
        synchronized(this){NumberOfThreads--;}
    }
}

Also, be aware that long-running execution in the actual http connector thread blocks all subsequent http requests - it might be a good idea to trigger background processing and just query that background process in later HTTP requests. That way you can also queue multiple invocations and not start a huge number of background threads at the same time. Keep in mind, there's a limited number of HTTP request handlers.

I'm assuming the try/finally will be your main problem (or an endless loop in your code) - synchronizing will solve rare race conditions, especially as you're speaking of a lot of code executed in this servlet.

You need to synchronize modification to NumberOfThreads


    public class myServlet extends HttpServlet {
        public int NumberOfThreads = 0;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(NumberOfThreads); synchronized(this){NumberOfThreads++;} .... ..a lot of code.. .... synchronized(this){NumberOfThreads--;} } }

The different servlet threads are caching NumberOfThreads . You have to mark it as volatile .

public volatile int NumberOfThreads = 0;

But, I have a feeling that there are better ways of doing what you probably want to achieve with this code.

You are doing it wrong.

System.out.println(ManagementFactory.getThreadMXBean().getThreadCount());

Alternatively, just use JMX/JConsole.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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