0

Sun の「Core Servlets and JavaServer Pages vol 2」でセッション カウンターの例を見ました。
カウンターは単純に構築され、 /を使用HttpSessionListenerしてセッション数を増減します。sessionCreatedsessionDestroyed

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それにアクセスしてカウンター値を取得できます。
同期ブロックはありません。
それは安全ですcurrentSessionCountvolatile

currentSessionCountCPUレジスタにキャッシュされ、リクエストを処理する他のスレッドの正確な値で表示されない可能性がありservletsます?

4

2 に答える 2

1

サーブレット 3.0 の仕様には次のように書かれています (§ 11.5):

リスナー インスタンスとスレッド化

[...]

コンテナーは、結果の通知を属性リスナー クラスに同期する必要はありません。状態を維持するリスナー クラスは、データの整合性に責任があり、このケースを明示的に処理する必要があります。

いいえ、コードは安全ではありません。AtomicCounter を使用するか、カウンターへのアクセスを同期すると修正されます。

++ はアトミック操作ではないため、揮発性にしても安全にはなりません。したがって、他のすべてのスレッドは volatile のおかげで新しい値を認識しますが、競合状態の読み取りが原因でインクリメントを見逃す可能性があり、カウンターを並行してインクリメントします。

于 2013-07-15T14:56:17.967 に答える