• 締切済み

スレッドセーフについて

サーブレットの本にスレッドセーフを考慮してサーブレッドはプログラミングしろと書いてありました。 そこで疑問が発生しました。 1 JSPの場合はスレッドセーフって関係ないのですか? 2 Beanを使った場合そのBeanはスレッドセーフを考慮する必要があるのですか? よろしくお願いします。

みんなの回答

回答No.3

サーブレットをスレッドセーフを考慮してコーディングする事は非常に重要です。JSPもサーブレットなので同様。 意識していないと、テスト時に一人でテストするぶんには問題なくても、複数の人で一斉テストした場合に「別人問題」が起こったりします。#1の方が示している問題です。私も経験しちゃいました。 サーブレットのインスタンスは1つしかありません。(これ重要) ですから、リクエスト毎に変化するオブジェクトをインスタンス変数なんかに定義してあると、別人問題が起こります。 JSPの場合も、<%! %>タグで定義したものはサーブレットのインスタンス変数となるので注意です。

  • chi-kon
  • ベストアンサー率43% (58/132)
回答No.2

1.JSPは最終的にはサーブレットに翻訳されて実行されます。 よってJSPだから自動的にスレッドセーフっていうのはNOが答えだと。 2. 考慮する必要があります。 ただしそのBeanがフィールドをもっていないのであれば必要ないです。(そんなことありえるのか!って感じですけどね)

gorou
質問者

お礼

回答ありがとうございました。

  • dayowl
  • ベストアンサー率56% (84/148)
回答No.1

私もこのご質問に回答できるほど十分なスキルは持ち合わせていないのですが。。。 ツッコミがあること覚悟で書いてみます。(汗) まず「スレッドセーフ」の意味としては、 「マルチスレッド環境下で正しく動作すること」ですよね。 http://www.atmarkit.co.jp/icd/root/10/86966010.html 1 JSPの場合はスレッドセーフって関係ないのですか? JSPの場合は、ユーザーからのリクエストごとに個々のスレッドが発生すると記憶しています。 ですから、そこに記述するスクリプトに対してスレッドセーフを考慮する必要は無いと思います。 しかし、JSPの中で使用するクラスについてはスレッドセーフを考慮する必要があります。 というか、スレッドセーフは個々のクラスについて考慮すべきことではないかと思います。 スレッドセーフについての参考URL http://www.tetras.co.jp/yada/j_java_thrd_r.htm http://www-6.ibm.com/jp/developerworks/java/040409/j_j-jtp09263.html 2 Beanを使った場合そのBeanはスレッドセーフを考慮する必要があるのですか? スレッドセーフは個々のクラスについて考慮すべきことだと思いますから「必要あり」です。 でも、その本に書かれていた「スレッドセーフを考慮せよ」というのは、もっと比較的簡単な話のような気がします。 つまり、非常に大雑把に言い換えると、 「変数のスコープに注意」とか、 「サーブレットの場合は、複数のユーザーからほぼ同時にリクエストが送られることがあるからフィールド変数を多用しないように」 という程度なんではないかなと思いました。 例えば、こんなサーブレットで。。。 public class ServletTest extends HttpServlet { String p1 = ""; public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); String p1 = request.getParameter("POST_PARAMETER1"); String reault1 = getResult(p1); String reault2 = getResult(p1); out.println("POST_PARAMETER1 = " + p1); out.println("RESULT1 = " + result1); out.println("RESULT2 = " + result2); out.close(); } private String getResult(String param) { String result = new String(); ....(引数paramを使う何か時間のかかる処理) return result; } } 「p1」のようにクラス全体からアクセスできるフィールド変数は使っちゃダメですよね。 フィールド変数はマルチスレッド環境下で共有されますから、 ユーザーAからのリクエストを処理した直後にユーザーBのリクエストを受けたら、 ユーザーAのgetResultの処理中にp1の値がユーザーBからのリクエストの値に書き換えられてしまう可能性があるわけで、そうなると「result1」と「result2」の値が異なってしまう可能性がありますよね。 そのサーブレットの本では、そういうことが言いたかったんじゃないかと思う次第です。

gorou
質問者

お礼

詳しい回答ありがとうございました。 参考になりました。

関連するQ&A

専門家に質問してみよう