1

ASP.NETアプリケーションで作業しているときに、セッションキャッシュに何かを配置するか、実際にはセッションキャッシュの変数にアクセスすると、Ajaxクエリの非同期が停止することがわかりました。これは、セッションが基本的にブロックされるためであることがわかりました。ブラウザから2つのAjaxリクエストを同時に起動し、最初のリクエストが戻るのに少し時間がかかる場合、そのリクエストが完了するまで、セッションは最初のリクエストでロックされます。その時点で、2番目のAjaxリクエストが機能し始めます。

PHPでは、セッション変数へのアクセスがブロックされず、非同期のままになるように、書き込みのためにセッションを閉じる(および/または読み取り専用の方法で開く)オプションがあることを収集しました。

私はJavaであるアプリケーションを構築しており、おそらくTomcatで実行されています(必要に応じて他のコンテナーに変更できます)が、Javaに同じ問題があるか(セッション変数がブロックを読み取る)、または同じ救済策(早期終了、読み取り専用モード)。誰かが以前にその問題に遭遇したことがありますか?

4

2 に答える 2

2

Tomcatでは、HttpSessionに実装されていますorg.apache.catalina.session.StandardSession(ソースはこちら)。

ソースを見ると、 追加の同期なしで、への呼び出しHttpSession.getAttribute(String)HttpSession.setAttribute(String, Object)ほとんどがにチャネル化されていることがわかります。ConcurrentHashMap

これは、これらの呼び出しがのコントラクトを派生させることを意味しますConcurrentHashMapそのJavadocを引用する:

  • 取得操作はロックを必要とせず、すべてのアクセスを妨げる方法でテーブル全体をロックするためのサポートはありません。<..>取得操作(getを含む)は通常ブロックされないため、更新操作(putおよびremoveを含む)と重複する場合があります。
  • テーブルは内部でパーティション化されており、競合することなく、指定された数の同時更新を許可しようとします。ハッシュテーブルへの配置は基本的にランダムであるため、実際の同時実行性は異なります。
于 2012-10-24T21:23:45.557 に答える
0

このSOの回答HttpSessionで説明されているように、アクセスのスレッド同期が原因でブロッキングが発生しているようです

したがって、2番目のリクエストは1番目のリクエストが動作している間のみブロックされる必要がありますHttpSession(または、1番目のリクエストによって長期間保持される共有ロックがあるが、これはTomcatとは関係ありません)。

この同期はサーブレット仕様で必要とされるため、違反しようとしないでください。代わりに、アプリの読み取りまたは書き込みに必要な時間を最小限に抑えるようにアプリを作成してくださいHttpSession

さらに、上記で書いたように、複数のリクエストを順番に実行する追加のロックがある場合、ブロッキングが発生する可能性があります。2番目の要求をTomcatに送信したときに、Tomcatのスレッドダンプをいくつか作成して、2番目の要求で待機しているそのようなロックがあるかどうかを確認してください。

于 2012-10-24T21:21:31.113 に答える