Servlet not running in streaming mode
I have developed a simple server using Tomcat that runs a servlet.
The servlet calls the command line program, which takes about 20 seconds to execute, and then returns the result to the user via JSON. The problem is, if I do over 2 concurrent requests, the servlet blocks until one of the previous requests completes.
An example of this can be seen below - "Im in" is the top of the servlet, and the list of results is after the servlet is executed. All requests were made at the same time, but you can clearly see that they are not considered at the same time. What setting do I need to change in tomcat so that all requests are processed at the same time?
Im in Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE Im in FVFNT01 STOP_IDLE FVFNT03 STOP_IDLE FVFNT16 STOP_IDLE FVFNT17 STOP_IDLE
a source to share
Servlet requests are processed by default. There is no setting to enable / disable this behavior. This is confirmed by the JavaDoc for HttpServlet :
Servlets usually run on multithreaded servers, so keep in mind that the servlet must handle concurrent requests and be careful to synchronize access to shared resources.
However, if your servlet implements the SingleThreadModel marker interface , the servlet will only process one request each time. However, using this interface is generally considered bad practice, and since you did not mention it, I assume you are not using it.
Of course, even if you don't implement SingleThreadModel
, you can make any servlet single-threaded using (possibly inappropriate) synchronization like
class MyServlet extends HttpServlet {
private void Object sharedObject = new Object()
protected synchronized void doGet(HttpServletRequest req, HttpServletResponse resp) {
// method logic goes here
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
synchronized(sharedObject) {
// method logic goes here
}
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
synchronized(this) {
// method logic goes here
}
}
}
In the above example, only one thread can execute the same request method at a time, although it is possible (for example) for one thread to execute doPost()
while another is executing doGet()
.
If you don't understand why this is the case, I recommend that you read some reading about concurrent programming in Java before continuing with your problem.
a source to share
The problem is with your test client . This triggers requests synchronously. It has to run requests asynchronously, then the servlet can do the same :)
About the same question was asked 4 days ago, I posted an answer with sample code of how a test client should look like: Servlet requests are executed sequentially for no apparent reason in Glassfish v3 . You may also find it useful.
a source to share
The same request to the same server will be fueled as soon as you run the application on Tomcat (not through eclipse in debug mode).
A simple test case can be done: make some simple doGets that do the following:
PrintWriter printWriter = response.getWriter();
printWriter.append("doGet: Hello from testServlet! doing some thread check :)");
try{Thread.sleep(15*1000);}catch(Exception e){}
printWriter.close();
now fire up your web browser and run this servlet multiple times and you will see they all return at the same time (+ -). if the servlet has not been refueled, you expect the first one to return after 15 seconds, the second after 30 seconds, and so on ...
a source to share