55

また、セッションに保存されているオブジェクトの状態がわかっていることを保証するために、設定されているオブジェクトはスレッドセーフである必要がありますか。

また、私はウェブ上で次の使用を提案していることを読んでいました。

synchronized(session) {
  session.setAttribute("abc", "abc");
}

これは有効な提案ですか?

4

5 に答える 5

68

サーブレット 2.5 仕様:

要求スレッドを実行する複数のサーブレットは、同じセッション オブジェクトに同時にアクティブにアクセスできます。コンテナーは、セッション属性を表す内部データ構造の操作がスレッドセーフな方法で実行されるようにする必要があります。開発者は、属性オブジェクト自体へのスレッドセーフなアクセスを担当します。これにより、HttpSession オブジェクト内の属性コレクションが同時アクセスから保護され、アプリケーションがそのコレクションを破損させる可能性がなくなります。

これは安全です:

// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);

これは安全ではありません:

HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);

これは安全であるとは限りません:

// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
  Integer n = (Integer) session.getAttribute("foo");
  session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

この最後のアプローチが推奨されているのを見たことがありますが (J2EE の書籍を含む)、サーブレット仕様では動作が保証されていません。セッション ID を使用してミューテックスを作成することもできますが、より良い方法が必要です。

于 2009-03-05T21:34:53.830 に答える
2

それらはそうではありませんが、ほとんどの場合、クライアントは単一のスレッドでのみアクセスします。

異なるクライアントには異なるスレッドがあり、それぞれに独自のセッションがあります。

Eddie が指摘しているように、同じセッションにアクセスする 2 つのスレッドに直面する可能性がある状況の 1 つは、2 つの ajax 呼び出しが同じセッション属性を変更しようとしている場合です。そうでなければ、問題はありません。

于 2009-03-05T21:36:21.160 に答える