0

RollerSessionには次のコードがあります。

public static RollerSession getRollerSession(HttpServletRequest request) {
    RollerSession rollerSession = null;
    HttpSession session = request.getSession(false);
    if (session != null) {
        rollerSession = (RollerSession)session.getAttribute(ROLLER_SESSION);
        if (rollerSession == null) {
            // HttpSession with no RollerSession?
            // Must be a session that was de-serialized from a previous run.
            rollerSession = new RollerSession();
            session.setAttribute(ROLLER_SESSION, rollerSession);
        }
      ....

私は並行性の問題に慣れていません。ここでは、setAttribute を同時に更新する可能性のある 2 つの異なるスレッドによる原子性違反があるようです。そうですか?セッションがリクエストから取得されている場合、2 つのスレッドでセッションを共有できますか?

4

1 に答える 1

1

はい、あなたは正しいです、さらにそこには視界の問題もあります!IBMの投稿JavaRanchによると、get/set操作はスレッドセーフではありません。したがって、アプリに競合状態が必要ない場合は、同期する必要がありますが、同期を配置する場所には注意してください。

説明

リクエストスレッドを実行する複数のサーブレットは、同じセッションオブジェクトに同時にアクティブにアクセスできる場合があります。コンテナは、セッション属性を表す内部データ構造の操作がスレッドセーフな方法で実行されることを保証する必要があります。開発者は、属性オブジェクト自体へのスレッドセーフアクセスに責任があります。これにより、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);

-マクダウェルの答え

于 2012-07-20T03:09:38.150 に答える