2

このコードが行うことを効果的に実行している本番環境のコードがいくつかあります。

http://java.sun.com/products/java-media/2D/reference/faqs/index.html#Q_Can_I_use_Java2D_to_generate_d

これは問題なく動作しますが、動作に関する問題に気づきました。

サーブレットが要求され、一部の画像データがServletOutputStreamを介してブラウザに返される場合、画像が画面に表示される前に別の要求がトリガーされると、次のトレースでJaguarサーバー全体が必ずクラッシュします。

j com.sybase.jaguar.servlet.JaguarConnection.writeClient([BII)V + 0
j com.sybase.jaguar.servlet.JagHttp11OutputStream.writeChunk()V + 92
j com.sybase.jaguar.servlet.JagHttp11OutputStream.writeOut()V + 57
j com.sybase.jaguar.servlet.ResponseImpl.flushBuffer(Z)V + 93
j com.sybase.jaguar.servlet.ResponseImpl.flushBuffer()V + 17
j com.sybase.jaguar.servlet.JaguarOutputStream.flush()V + 19
j javax.imageio.stream.FileCacheImageOutputStream.close()V + 50
j javax.imageio.stream.ImageInputStreamImpl.finalize()V + 8

私がやろうとしていることは信頼できないと言っているいくつかの参考文献をオンラインで見つけました。

http://forums.sun.com/thread.jspa?trange=15&threadID=560000&forumID=20&tstart=0

ただし、正直なところ、EDTとは何かはわかりません。

誰かがこの問題に遭遇し、その回避策を作成することができましたか?

4

3 に答える 3

1

少なくとも EDT とは何かを言えば、それは Event Dispatch Thread であり、すべての AWT および Swing 操作が行われるスレッドです。
私の知る限り、画面にグラフィックを出力する操作であるため、JVM ごとに 1 つの EDT しか存在できません。あなたの操作がヘッドレスであることは理解していますが、おそらくルールはまだ適用されます.
正しい修正が何であるかはわかりません。おそらく、リクエスト スレッドごとに 1 つの JVM を生成しますか? 実用性があるかは不明…

于 2010-02-25T22:40:54.157 に答える
1

これは、一部のリクエスト スコープ変数がサーブレットのインスタンス変数として宣言されているように思えます。つまり、コードはスレッドセーフではありません。Web アプリケーションの存続期間中にサーブレットのインスタンスは 1 つだけです。すべてのリクエスト間で同時に共有されます。各リクエストは個別のスレッドとしてカウントされます。変数 X (画像など) をサーブレットのインスタンス変数として宣言し、それをスレッド A (リクエスト A) に設定し、処理中にスレッド B が同じサーブレットを使用して変数 X をオーバーライドするとします。これにより、スレッド A で問題が発生します。出力への処理中に変数が変更されたためです。

したがって、リクエストまたはセッション スコープの変数をサーブレットのインスタンス変数として割り当てないでください。

public class ImageServlet extends HttpServlet {

    private Image image;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        this.image = imageDAO.find(request.getPathInfo()); // Not threadsafe!! image is been shared among all requests.
        // ...
    }
}

むしろそう

public class ImageServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        Image image = imageDAO.find(request.getPathInfo()); // Threadsafe.
        // ...
    }
}

このように、各スレッドには独自の変数があります。

つまり、EDT は「イベント ディスパッチャ スレッド」です。私は Swing をやっていないので、それについて多くを語ることはできませんが、彼が、すべての変数をスレッドローカルに保つ (つまり、サーブレットのメソッド ブロック内ですべて宣言する) ことで、それらが共有されるのを避けるように指示しようとしているのは理にかなっています。すべてのスレッド (リクエスト)。

于 2010-02-25T23:20:03.593 に答える
0

前のページの画像が取得されてレンダリングされる前に、同じブラウザーが新しい URL に移動しようとしているということですか? これにより、ブラウザが画像の取得に使用されたネットワーク接続を閉じる可能性があります。サーブレットの実装によっては、例外がキャッチされてログに記録される可能性がありますが、実際のエラー状況は存在しません (ブラウザはサーブレットの前に接続を切断しただけです)。作業を終了しました)。

ここにスタック トレースを投稿していますが、JaguarConnection クラスによってスローされる実際の例外は何ですか?

于 2010-02-25T22:58:02.323 に答える