我在Sun的“ Core Servlets and JavaServer Pages vol 2”中看到了带有会话计数器的示例。 计数器仅仅是建立在HttpSessionListener和递增/递减会话数与sessionCreated/ sessionDestroyed:
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吗?
servlets
currentSessionCount
volatile
可以currentSessionCount缓存在CPU寄存器中,并且对于使用servlets?
Servlet 3.0的规范规定(第11.5节):
侦听器实例和线程 […] 不需要容器将结果通知同步到属性侦听器类。维护状态的侦听器类负责数据的完整性,并应明确处理这种情况。
侦听器实例和线程
[…]
不需要容器将结果通知同步到属性侦听器类。维护状态的侦听器类负责数据的完整性,并应明确处理这种情况。
所以不,代码不安全。使用AtomicCounter或同步对计数器的访问即可对其进行修复。
使它易失并不能使其更安全,因为++不是原子操作。因此,由于易失性,每个其他线程都将看到新值,但是由于竞争条件读取,您可能仍会错过增量,然后并行增加计数器。