PDA

View Full Version : New thread in HttpSessionListener


titiwangsa
Jun 18th, 2007, 01:13 AM
i'm using spring 2.0.4 and the daos are simple jdbc daos
my web framework is jsf with no spring mvc or even spring web flow

i'm executing a method from a service bean in another thread
is this code safe?

public class VisitorCountSessionListener implements HttpSessionListener {

private final String BEAN_VISITOR_SERVICE = "visitorService";

public void sessionCreated(final HttpSessionEvent event) {
final Thread thread = new Thread() {
public void run() {
final VisitorService visitorService = getVisitorService(event);
visitorService.incrementVisitor();
}
};
thread.start();
}

private VisitorService getVisitorService(HttpSessionEvent event) {
final WebApplicationContext wac = getWebApplicationContext(event);
return (VisitorService) wac.getBean(BEAN_VISITOR_SERVICE);
}

private WebApplicationContext getWebApplicationContext(
HttpSessionEvent httpSessionEvent) {
final HttpSession session = httpSessionEvent.getSession();
final ServletContext sc = session.getServletContext();
return WebApplicationContextUtils.getRequiredWebApplicati onContext(sc);
}

public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
// Do nothing

}
}


the important part is just

public void sessionCreated(final HttpSessionEvent event) {
final Thread thread = new Thread() {
public void run() {
final VisitorService visitorService = getVisitorService(event);
visitorService.incrementVisitor();
}
};
thread.start();
}



i mean is it ok to get a service bean from the application context
and use in another thread.
would there be any concurrency problems?

i'm doing this because the visitorService.incrementVisitor() function
can sometimes take a while
and the requested page cannot be started till after the visitorService.incrementVisitor() function has ended

so, i'm letting the session start and visitor count can be incremented in the background.

to put it to another level
would this code be ok?

public void sessionCreated(HttpSessionEvent event) {
final Thread thread = getVisitorThread(event);
thread.start();
}


where the thread is a prototype bean in the application context?

so
1. is starting a new thread containing a service bean (and daos inside the service bean) safe/good practice?
2. if 1 is yes, then is my posted code safe?
3. if 2 is yes, then is getting a configured, prototyped Thread bean from the application context safe/ good practice?

thanks..

cwilkes
Jun 18th, 2007, 12:10 PM
Not that this answers your question, but I would look into improving your vistorService so that it is asynchronous by using a queue. That way it returns immediately and you won't be blocked.

titiwangsa
Jun 18th, 2007, 12:29 PM
in other words, start a new thread in the service?

julien.dubois
Jun 18th, 2007, 01:10 PM
I think cwilkes means using a message queue, like JMS. This will help you have your service asynchronous, without you having to play around with Threads.

Jörg Heinicke
Jun 18th, 2007, 07:35 PM
i mean is it ok to get a service bean from the application context and use in another thread. would there be any concurrency problems?

1. I wonder if it is possible to create your own threads in listeners. At least in some managed environments like EJB containers this might not be allowed.
2. I can't see a concurrency problem if your service itself is stateless.
3. There will be no problem as long as you don't use some thread-bound technologies like transactions or session-scoped beans.
4. The setup is indeed a bit strange, but if your requirements really require it ...

to put it to another level would this code be ok?

public void sessionCreated(HttpSessionEvent event) {
final Thread thread = getVisitorThread(event);
thread.start();
}

where the thread is a prototype bean in the application context?


There is technically no difference, is it?

Jörg