I saw an example with session counter in Sun's "Core Servlets and JavaServer Pages vol 2".
Counter is simply build on HttpSessionListener
and increments/decrements session count with sessionCreated
/sessionDestroyed
:
public class SessionCounter implements HttpSessionListener {
private int currentSessionCount = 0;
public void sessionCreated(HttpSessionEvent event) {
currentSessionCount++;
}
...
public int getTotalSessionCount() {
return(totalSessionCount);
}
... // counter decrement, self registering in context attribute etc.
Listener register itself in context, so servlets
can access it and get counter value.
There is no synchronized block.
Is it safe, that currentSessionCount
is not volatile
?
Can currentSessionCount
be cached in CPU register and not visible with exact value for other threads that serve request with servlets
?
The specification of Servlet 3.0 says (§ 11.5):
Listener Instances and Threading
[...]
The container is not required to synchronize the resulting notifications to attribute listener classes. Listener classes that maintain state are responsible for the integrity of the data and should handle this case explicitly.
So no, the code is not safe. Using an AtomicCounter or synchronizing the access to the counter fixes it.
Making it volatile doean't make it safer, because ++ is not an atomic operation. So every other thread will see the new value thanks to volatile, but you might still miss increments due to a race condition reading, then incrementing the counter in parallel.
This would be safe.
public class HttpSessionListenerTest implements HttpSessionListener {
final private AtomicInteger sessionCount = new AtomicInteger(0);
@Override
public void sessionCreated(HttpSessionEvent event) {
sessionCount.incrementAndGet();
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
sessionCount.decrementAndGet();
}
public int getTotalSessionCount() {
return sessionCount.get();
}
}
来源:https://stackoverflow.com/questions/17602477/session-counter-with-httpsessionlistener-and-session-count-variable-access