Reputation: 1378
I am wondering that if servlet containers like Tomcat, Jetty etc already use nio to read and write data back, is there really a need of using setWritelistner
and setReadListner
on servlet input and output streams? Is there any additional performance gain?
Upvotes: 12
Views: 7273
Reputation: 718826
The benefit is not directly1 about "performance gain". The purpose of those methods is to avoid a request thread (in async mode) from blocking when it reads input (POST) data or writes the document.
There is an example in the Java EE7 tutorial: "17.13.1 Reading a Large HTTP POST Request Using Non-Blocking I/O" (link updated).
This is orthogonal to Tomcat's use of nio under the covers.
1 - There is an indirect performance benefit. When it is likely for threads to block on network I/O, an alternative strategy for increasing throughput is to increase the number of worker threads. But that increases the memory footprint (among other things) resulting in more "overheads".
Upvotes: 7
Reputation: 17397
Async IO can have a profound effect on performance in certain scenarios. My experience is mostly with the ASP.NET equivalent, but it should apply here as well.
A servlet has a finite number of threads to handle requests. If there is any sort of blocking IO (a network request, database query, etc) the thread handling the request remains in use while it sits around waiting for the IO to complete. In high volume scenarios, this can starve the thread pool and cause serious performance degradation.
With async IO, IO does not block the request thread. Instead, a callback is registered and subsequently called when the IO completes. In the meantime, the thread is returned to the thread pool where it can continue to serve other requests.
Upvotes: 4
Reputation: 5223
Tomcat reads the headers (and does so in a non-blocking mode for NIO) but reading request bodies is an application concern and is performed with blocking IO (till Servlet 3.0 requirement of the specification). Likewise, writing the response is done with blocking IO as that is also a requirement of the specification.
All of this changes with Servlet 3.1.
You may want to see email Thread for this
Below para and code sample is from Java EE 7 Recipies it explains use of setWritelistner and setReadListner
To implement a nonblocking I/O solution, new programming interfaces have been added to ServletInputStream and ServletOutputStream, as well as two event listeners: ReadListener and WriteListener. ReadListener and WriteListener interfaces make the servlet I/O processing occur in a nonblocking manner via callback methods that are invoked when servlet content can be read or written without blocking. Use the ServletInputStream.setReadList ener(ServletInputStream, AsyncContext) method to register a ReadListener with a ServletInputStream, and use the I/O read ServletInputStream.setWriteListener(ServletOutputStream,AsyncContext) method for registering a WriteListener. The following lines of code demonstrate how to register a ReadListener implementation with a ServletInputStream:
AsyncContext context = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new ReadListenerImpl(input, context));
Upvotes: 8