会话计数器具有HttpSessionListener和会话计数变量访问权限

我在Sun的“Core Servlets和JavaServer Pages vol 2”中看到了一个带会话计数器的例子。
Counter简单地构建在HttpSessionListener并使用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. 

监听器在上下文中注册自己,因此servlets可以访问它并获得计数器值。
没有同步块。
是否安全, currentSessionCount volatile

currentSessionCount可以缓存在CPU寄存器中,并且对于使用servlets提供请求的其他线程的精确值是不可见的?

Servlet 3.0的规范说(§11.5):

监听器实例和线程

[…]

容器不需要将生成的通知同步到属性侦听器类。 维护状态的监听器类负责数据的完整性,并应明确处理此情况。

所以不,代码不安全。 使用AtomicCounter或同步对计数器的访问权限可以修复它。

使它变得不稳定并不会使它更安全,因为++不是primefaces操作。 所以每个其他线程都会看到新值,这要归功于volatile,但是由于竞争条件读取,你可能仍会错过增量,然后并行递增计数器。

这样会很安全。

 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(); } }