- How are Threads allocated to handle Servlet request?
- 1 Answer 1
- Create Thread In Java Web Application
- 1) Create Thread Using ServletContextListener
- ThreadListenerExample.java
- web.xml
- Package Structure
- 2) Create Thread Using HttpServlet
- ThreadServletExample.java
- web.xml
- Package Structure
- Threading in Java REST web service
- 2 Answers 2
- Java concurrency : Making webservice access threadsafe
- 3 Answers 3
How are Threads allocated to handle Servlet request?
Can someone please explain what is thread per request and thread per connection? Which model do servlets work on? How threads are allocated to handle HTTP requests? Is it thread/request or connection? And let’s say if I want to perform a time consuming task in my Servlet ‘s doGet() method asynchronously, I start a new thread using Java executors so that lengthy calculations are done in a separate thread and response is sent right away. Now does that ensure that I have freed the thread which had been processing my HttpServletRequest or is it still being used because a child thread is still running?
1 Answer 1
Per request means when an HTTP request is made, a thread is created or retrieved from a pool to serve it. One thread serves the whole request. Thread per connection would be the same thing except the thread is used for an entire connection, which could be multiple requests and could also have a lot of dead time in between requests. Servlet containers are thread per request. There may be some implementations that offer thread per connection, but I don’t know, and it seems like it would be very wasteful.
Creating a thread inside another thread doesn’t establish any special relationship, and the whole point of doing so in most cases is to let the one thread do more work or terminate while the other thread continues working. In your scenario, using a different thread to do work required by a request will, as you expect, allow the response to be sent immediately. The thread used to serve that request will also be immediately available for another request, regardless of how long your other thread takes to complete. This is pretty much the way of doing asynchronous work in a thread-per-request servlet container.
Caveat: If you’re in a full Java EE container, threads may be managed for you in a way that makes it a bad idea to spawn your own. In that case, you’re better off asking the container for a thread, but the general principles are the same.
Create Thread In Java Web Application
Create Thread In Java Web Application explains about implementing a background thread in a java web application so that you can do some logic behind these background thread.
You can achieve thread implementation in j2ee web application several ways. For example if you are using application servers like Jboss,Weblogic & Websphere, you have more possible ways to do this. But here we are targeting for both servlet containers like Tomcat, jetty etc and application servers like JBOSS, Weblogic etc.
We are showing implementing Thread in Java web application two different ways:
1) Create Thread Using ServletContextListener 2) Create Thread Using HttpServlet
Required Libraries
1) Create Thread Using ServletContextListener
For the entire web application, there will be only one ServletContext, so ServletContextListner notified when any change happens to the ServletContext lifecycle
You can see more about implementing interface ServletContextListener ServletContextListener Example here.
Here we are using ScheduledExecutorService when contextInitialized method is invoked , we are printing the current date at periodic intervals, you can change the logic inside run method as per your requirements. After doing the tasks, you can able to clean up the thread (shutdown) when contextDestroyed method is invoked.
More clarification, please check the below code
ThreadListenerExample.java
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ThreadListenerExample implements ServletContextListener private ScheduledExecutorService scheduler = null ;
public void contextInitialized ( ServletContextEvent sce ) if (( scheduler == null ) || ( !scheduler.isTerminated ())) scheduler = Executors.newSingleThreadScheduledExecutor () ;
scheduler.scheduleAtFixedRate ( new ScheduledTask () , 0 , 3 , TimeUnit.SECONDS ) ;
>
>
public void contextDestroyed ( ServletContextEvent sce ) try System.out.println ( «Scheduler Shutting down successfully » + new Date ()) ;
scheduler.shutdown () ;
> catch ( Exception ex ) >
>
>
class ScheduledTask extends TimerTask public void run () System.out.println ( new Date ()) ;
>
>
web.xml
web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> listener> listener-class>com.listener.ThreadListenerExamplelistener-class> listener> web-app>
Package Structure
Output
Fri Apr 29 08:13:51 IST 2014 Fri Apr 29 08:13:54 IST 2014 Fri Apr 29 08:13:57 IST 2014 Fri Apr 29 08:14:00 IST 2014 Fri Apr 29 08:14:03 IST 2014 Fri Apr 29 08:14:06 IST 2014 Fri Apr 29 08:14:09 IST 2014 Fri Apr 29 08:14:12 IST 2014 Fri Apr 29 08:14:15 IST 2014 Fri Apr 29 08:14:18 IST 2014 Fri Apr 29 08:14:21 IST 2014 Fri Apr 29 08:14:24 IST 2014 Fri Apr 29 08:14:27 IST 2014 Fri Apr 29 08:14:30 IST 2014 Fri Apr 29 08:14:33 IST 2014 Fri Apr 29 08:14:36 IST 2014 Fri Apr 29 08:14:39 IST 2014 Fri Apr 29 08:14:42 IST 2014 . . .
2) Create Thread Using HttpServlet
Here we are using Thread in java when init() method of HttpServlet invoked , we are printing the current date at periodic intervals, you can change the logic inside run method as per your requirements.
Also see that we are used inside web.xml, this is for preloading the servlet
More clarification, please check the below code
ThreadServletExample.java
public class ThreadServletExample extends HttpServlet implements Runnable
private static final long serialVersionUID = 1L ;
public void init () try Thread thread = new Thread ( this ) ;
thread.start () ;
> catch ( Exception e ) e.printStackTrace () ;
>
>
@Override
public void run () while ( true ) try System.out.println ( new Date ()) ;
Thread.sleep ( 5000 ) ;
> catch ( InterruptedException e ) e.printStackTrace () ;
>
>
>
>
web.xml
web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> servlet> servlet-name>ThreadServletExampleservlet-name> servlet-class>com.thread.ThreadServletExampleservlet-class> load-on-startup>1load-on-startup> servlet> web-app>
Package Structure
Output
Fri Apr 29 08:13:51 IST 2014 Fri Apr 29 08:13:54 IST 2014 Fri Apr 29 08:13:57 IST 2014 Fri Apr 29 08:14:00 IST 2014 Fri Apr 29 08:14:03 IST 2014 Fri Apr 29 08:14:06 IST 2014 Fri Apr 29 08:14:09 IST 2014 Fri Apr 29 08:14:12 IST 2014 Fri Apr 29 08:14:15 IST 2014 Fri Apr 29 08:14:18 IST 2014 Fri Apr 29 08:14:21 IST 2014 Fri Apr 29 08:14:24 IST 2014 Fri Apr 29 08:14:27 IST 2014 Fri Apr 29 08:14:30 IST 2014 Fri Apr 29 08:14:33 IST 2014 Fri Apr 29 08:14:36 IST 2014 Fri Apr 29 08:14:39 IST 2014 Fri Apr 29 08:14:42 IST 2014 . . .
Threading in Java REST web service
I have a REST web service which is consuming too many CPU resources when the number of requests gets too high. This is believed to be caused by a while() loop in the response generation, which normally takes a few milliseconds to complete, however under some circumstances it can take a few seconds. The fix for this appears to be to use wait() and notify() according to this however I don’t understand why this will reduce CPU usage? Would this new thread be handled outside the web service, thereby freeing it up to handle more requests? Can someone please explain? Thanks! Jon. Edit: I may have found my own answer here It seems that my code of result = get() constantly polls until there is a response, which consumes more CPU resources. By placing this in a thread, less resources are consumed. Is this a correct understanding?
Hard to say since we don’t have your code to verify. If in your case, you have two thread, one that will produce something and the other which polls constantly to see if the producer produced something, then yes, you should avoid that and you can organize the Threads execution with the use of wait and notify.
Apologies for the lack of code, it’s a substantial calculation and I don’t know where the problem area is. I think Stephen has uncovered the issue below though.
2 Answers 2
Is this a correct understanding?
A loop that continually polls something until there is a response is very wasteful. If you add a sleep between each poll, you reduce the CPU usage, but at the cost of reduced responsiveness for individual requests . compared to what is achievable if you do it the right way.
Without knowing exactly what you are doing (what you are polling, and why) it is a bit difficult to say what the best solution is. But here are a couple of possible scenarios:
- If your web service is waiting for a response from an external service, then the simple solution is to just do a blocking read, and configure your web server with more worker threads.
- On the other hand, if your web service is waiting for a computation to complete, a new thread and wait / notify . or one of the higher level synchronization classes . may be the answer.
- If you need to handle a really large number of these blocking requests in parallel, that is going to require a lot of threads and hence a lot of memory, and other things. In that case you need to consider an web container that breaks the one-thread-per-request constraint. The latest version of the Servlet spec allows this, as do some of the alternative (non-Servlet) architectures.
. I think the issue is your point 2, that the service is simply just waiting for the computation. So, by simply threading this computation will free up resources in the service?
If what you are describing is true, then running the computation in a different thread won’t make it go much quicker. In fact, it could make it go slower.
The ultimate bottleneck is going to be CPU capacity, disc bandwidth and / or network bandwidth. Multi-threading is only going to make an individual request go faster if you can effectively / efficiently use 2 or more processors on the same request at the same time. It will only make your throughput better to the extent that it allows requests to run while others are waiting for external events; e.g. network responses to arrive, or file read/write operations to complete.
What I think you actually need to do is to figure out why the computation is taking so long and try and fix that:
- Are your database queries inefficient?
- Are fetching result-sets that are too large?
- Do you have a problem with your schemas?
- Poor choice of indexes?
- Or are you simply trying to do too much on a machine that is too small using the wrong kind of database?
There are various techniques for measuring performance of an application service and a database to determine where the bottlenecks are. (Start with a Google search . )
Java concurrency : Making webservice access threadsafe
I’d like to know the correct / best way to handle concurrency with an Axis2 webservice. Eg, given this code:
public class MyServiceDelegate < @Resource UserWebService service; // Injected by spring public CustomerDTO getCustomer() < String sessionString = getSessionStringFromCookies(); service.setJSESSIONID(sessionString); CustomerDTO customer = service.getCustomerFromSessionID(); >>
- ThreadA : service.setJSESSIONID(«threadA»)
- ThreadB : service.setJSESSIONID(«threadB»)
- ThreadA : service.getCustomerFromSessionID // service.sesionID == «threadB»
If so, what’s the most appropriate way to handle this situation? Should I use a resource pool for service? Or should I declare service as synchronized?
public CustomerDTO getCustomer() < synchronized( service ) < service.setJSESSIONID(sessionString); CustomerDTO customer = service.getCustomerFromSessionID(); >>
Or, is there another, more appropriate way to handle this problem?
3 Answers 3
Would each thread have its own Delegate object and hence its own UserWebService service?
In the simple case, if delegates are created on the stack the threads would be independent.
If the cost of creation is high, have a pool of the delegate objects. Taking one from teh pool is comparativley cheap. You need to be very careful with housekeeping, but effectively this is what is done with database connections. Some environments have utility classes for managing such pooling — tends to be preferable to rolling your own.