1

OpenCMS の安定性に問題があります。スレッド ダンプを実行すると、多くのスレッド (400) がsynchronized (m_processingFiles)次のコードのブロックで待機しています。

public class CmsJspLoader ... {
...

private static Set m_processingFiles = Collections.synchronizedSet(new HashSet());

...
...
...
public String updateJsp(...) {
....

while (m_processingFiles.contains(jspVfsName)) {
    // wait a little bit until the first thread finishes
    try {
        synchronized (m_processingFiles) {
            m_processingFiles.wait(100);
        }
    } catch (InterruptedException e) {
        // ignore
    }
}
...
}
...
}

コードは OpenCMS の一部です。notify()コードのどこにもありません。表示されたブロック内では、状態の変化や共有変数の読み取りはありません。syncただし、400 のスレッドが待機しています。つまり、これを通過するだけでsync、最後のスレッドは 40 秒待機する必要があります!!!

私は単にその目的を理解していません。私が見ていないものはありますか?

4

2 に答える 2

2

スレッドが に追加し、さらに作業を行ってから から削除するコード内の場所が必要です。そうでない場合、他のスレッドはそのループで永遠に続きます。何らかの理由で、実装者は、他の処理が行われている間、他のスレッドを実行したくありませんでした。jspVfsNamem_processingFilesjspVfsNamem_processingFileswait()whileupdateJsp

jspVfsNameコードを調べて実際の内容を確認し、コード内で追加/削除できる場所を見つけることをお勧めしますm_processingFiles。おそらく、作成者がis in のupdateJspときに実行したくなかった理由も理解できるでしょう。jspVfsNamem_processingFiles

それが見つかったら、その「その他の」コードを調べて、jspVfsNameに追加できm_processingFiles決して削除できないかどうかを確認できます。もしそうなら、それは(自然に)ライブロックを引き起こし、安定性の問題を説明します.

それとも、それがupdateJsp非常に頻繁に呼び出され、変更する「他の」コードm_processingFilesも非常に頻繁に呼び出されて、同時実行性の大きなボトルネックが発生する可能性がありますか? アプリに何か問題があり、updateJsp必要以上に頻繁に呼び出されている可能性があります (おそらく、新しい JSP ファイルがサーバーに配置されるたびではなく、すべての要求で)。

updateJspが非常に頻繁に実行されているが、アプリの問題が原因ではない場合は、単純にwait()期間を短くしてみてください。それは何も害を及ぼすべきではありません-待機中のスレッドjspVfsNameがまだm_processingFilesより頻繁にあるかどうかをチェックするだけです。100 ミリ秒は、CPU 用語では非常に長い時間です。

于 2012-09-15T07:15:18.907 に答える
2

notify または notifyAll 呼び出しがない場合、これは基本的に 100 ミリ秒のスリープのように動作します。100 ミリ秒後、スレッドは復帰して続行します。同期ブロック内の待機以外に何もないと仮定すると、これは単なる奇妙なスリープ方法です。同期ブロックがメモリバリアをトリガーすることによって引き起こされる他の影響がいくつかある可能性があります。そのため、微妙なスレッド セーフが行われている可能性があります。

ここでスレッド ダンプを解釈する際に注意すべきことの 1 つは、ブロックされた 400 のスレッドが同期ブロックに入るのを待っているか、待機中ですか? スレッドが待機に入ると、本質的に同期ブロックからロックが解放され、別のスレッドがそれに入ることができます。スレッドが待機から復帰すると、ロックが再取得されます。

スレッド ダンプに「モニター エントリを待機中」などのメッセージが表示される場合、1 つのスレッドが同期ブロックにあり、他のすべてのスレッドが入ろうとしています。これは、ここに重大な並行性の問題があることを示唆しています。

ただし、スレッド ダンプに「in Object.wait()」のようなものが表示される場合は、スレッドが 100 ミリ秒待機中であり、他のスレッドが同期ブロックに自由に入ることができることを意味します。この場合、ループ条件がまだ false であることを意味するため、待機中のスレッドで何が起こっているかではなく、その側で何が起こっているかを見てください。

そうは言っても、プロセスの反対側が何であれ、notify / notifyAll を実行できる場合は、ウェイクアップとスレッドがまだスリープ状態であることを確認するための遅延とコストを削減できます。

于 2012-09-15T07:11:38.447 に答える