• ベストアンサー

Servletにおけるスレッド間でのグローバル変数の関係

お世話になっております。 サーブレットクラスにて定義したグローバル変数へ、それぞれ別のスレッドからアクセスした場合、 それぞれの値には関連性が無いと認識していたのですが、それは誤りでしょうか? グローバル変数を有するサーブレットクラスを作成し、2つのスレッドを流したところ、1つ目のスレッドでセットした値が、後追いで流した2つ目のスレッドでセットした値に置き換わってしまいました。 それぞれの値を関連性の無いようにしたいのですが どのようにしたら良いのか、ご存知の方いらっしゃいましたらご教授願います。 宜しくお願い致します。

  • Java
  • 回答数4
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • fortranxp
  • ベストアンサー率26% (181/684)
回答No.3

その他の方法では SingleThreadModelを実装する。 このパターンですと リクエストごとにインスタンスを 生成するようになります。 方法は public class Sample extend HttpServlet     implements SingleThreadModel { です。

kawakami2005
質問者

お礼

ありがとうございます。 今回の場合、こちらの方法が一番修正箇所が少なくなりそうなので、 こちらの方法を取らせていただく事にしました。 貴重なご意見ありがとうございました。

その他の回答 (3)

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がると申します。割合に典型的な「threadアンセーフなバグ」かと思われます。 threadの概念は確かに若干面倒なのですが、Javaでサーブレットをやるのであれば、習得はMustになります。 まずは言語云々以前に「thread」と、「thread safeな実装」について学ばれるとよろしいかと。 そうですねぇ。一つヒントとしては「processとthreadはどこがどう違うのか? なぜ双方が発生したのか? 特に、メモリ保護の観点から。」という問いに正しく答えられるようになると、大分違うかと思われます。 googleあたりを調べられると、色々と出てくると思いますので。

kawakami2005
質問者

お礼

ご回答ありがとうございます。 Javaに関する根本的な部分での理解が不足していました。 大変貴重なご意見ありがとうございます。 今回ご回答いただいた皆様にポイントを割り振りたいところなのですが、2名までということで申し訳ないです。

noname#18558
noname#18558
回答No.2

ThreadLocalとは、java.lang.Threadクラスのことです。 メソッドのローカル変数のことではございません。 Thread単位で値を管理することができます。 詳しくは、JavaDocをご覧下さい。 Sessionとは、javax.servlet.http.HttpSessionクラスのことです。 サーブレットでは常識なので検索でも参考書でもすればすぐに見つかると思います。

kawakami2005
質問者

お礼

ご丁寧に説明いただき大変助かりました。 ありがとうございます。 もっと勉強しなければと痛感いたしました。

noname#18558
noname#18558
回答No.1

まず、Javaにはグローバル変数というのはありません。 おそらく、インスタンス変数のことでしょうか。 アプリケーションサーバーによって異なりますが、 サーブレットインスタンスは、複数スレッドで共有されます。 したがって、その処理は正しい動きです。 一般的に、サーブレットクラスにインスタンス変数を持たないのは常套です。 スレッドごとに別の値を持ちたい場合は、多くの場合ThreadLocalの変数か、Sessionにしたりします。

kawakami2005
質問者

補足

大変参考になるご意見 ありがとうございます。 つきましては、お恥ずかしながら 重ねて質問させていただきたいのですが > スレッドごとに別の値を持ちたい場合は、多くの場合ThreadLocalの変数か、Sessionにしたりします。 「ThreadLocalの変数」というのは メソッド毎にローカル変数を定義するという認識で間違いないでしょうか? また「Session」というのが具体的にどういうことでしょうか。 もしお時間に余裕がございましたら、ご教授いただければ幸いです。 よろしくお願い致します。

関連するQ&A

  • スレッドセーフにするべきクラスについて。

    スレッドセーフにするべきクラスについて。 マルチスレッドで動くクラスはスレッドセーフにしなければならない。 とよく聞きます。ですが、どのクラスがマルチスレッドで動くのかどうかを判定する基準がよく分かっていません。 例えばサーブレットやJSP、Springでシングルトンにしたクラスなどは、スレッドセーフを意識しないといけないんだなと分かります。あとはThreadを拡張したクラスもそうなんだろうと思っています。 ただそれ以外のクラスでスレッドセーフを意識しなければならない場合、どこをみて判断すればよいのでしょうか?サーブレットから呼ばれるアクションクラスはスレッドセーフにしなければいけない・・・? そこのところがよくわかっていないため、クラスを作成する際にメンバ変数に状態を保持する変数を入れて良いんだろうかと悩んでしまいます。 申し訳ありません。アドバイスを頂けると嬉しいです。

    • ベストアンサー
    • Java
  • マルチスレッドでのインスタンス変数

    http://itpro.nikkeibp.co.jp/article/COLUMN/20070820/279950/ このサイトに以下ような趣旨の記述があり、信じられない気持ちでいっぱいです。 「マルチスレッドのケース(たとえばサーブレットでは、)インスタンス変数はヒープ領域に 保持されるので、複数のスレッドからアクセスされるので情報が書き換えられる場合がある」 信じられないのは、インスタンス変数が書き換えられるということです。 サーブレットではインスタンス変数が共有されるのは理解していますが、 サーブレットから呼ばれるインスタンスで定義されているインスタンス変数も それに該当するのでしょうか。 それとも、サーブレット内だけの話で、サーブレットから呼ばれるインスタンスでは インスタンス変数は独立していると思ってよいでしょうか。 後者の認識ですが、こういう書き方をされると、サーブレットから呼ばれた先でも インスタンス変数が共有されると読めて、怖くて仕方ないです。

    • ベストアンサー
    • Java
  • サーブレット スレッドセーフについて

    サーブレットのインスタンス変数、クラス変数はスレッドセーフではありませんが、 doGet などのほかに勝手に作ったメソッドは、スレッドで動作するのでスレッドセーフと考えていいでしょうか?

    • ベストアンサー
    • Java
  • java servlet で大域変数

    SERVLETで大域変数(count)を定義したいです。 ・ページの中のボタンを押すと他のservletのクラスを呼び、countの値を一つ 増やす。 ・その新しいページでも、ボタンを押すと同じcountの値がもう一つ増え、また他のservletを呼ぶ。 ……… (プログラムで使うすべてのservletのクラスでcountを有効にしたい) といった感じのプログラムを作るとしたら、 どこで、どのようにcountを定義すればいいでしょうか?

    • ベストアンサー
    • Java
  • マルチスレッド下でのインスタンス変数・クラス変数

    よろしくお願いします。  マルチスレッド下で動作するクラスを作成しています。データにアクセスするためのオブジェクトを クラスのフィールド値として保持し、使い回しを行いたいと考えています。このデータアクセスオブジェクト(以下Dao)内では特にフィールドは使用せず、全てローカル変数のみで動作するようになっています。Dao自体は初回のクラス生成時にstatic処理にてフィールドにセットされます。  このDaoを保持するフィールドは、staticなクラス変数が良いのか、インスタンス変数として保持する方が良いのか迷っております。  クラス変数ならばPermanent領域をオブジェクト1つ分のメモリ使用で済み、インスタンス変数だとスレッド毎にheapを使い、処理数が増えるとメモリ圧迫しちゃう?と安易に考えてしまったりしています。  ご意見・ご助言よろしくお願い致します。

    • ベストアンサー
    • Java
  • インスタンス変数とクラス変数の違い

    1つのクラスオブジェクト内のインスタンス全てで共有できる クラス変数 @@a と、 同じインスタンス内であればメソッドの定義を越えてその値を 参照したり、変更したりできるインスタンス変数 @a のスコープの違いをお手すきでしたらご指導願えませんか? あとクラス変数にはセッターやゲッター等のアクセスメソッドを 設定できるんですか? いろいろ知りたいです。

    • ベストアンサー
    • Ruby
  • servletのマルチスレッドとはどこまで意識をする必要があるのか?

    「servletはマルチスレッドを意識して実装しなくてはいけない」とよく聞きます。 マルチスレッドを意識しなければならないのは、HttpServletを継承したクラスのみなのでしょうか? それとも、そこからインスタンス化される汎用クラスなどもマルチスレッドを意識し、インスタンス変数は悪とされるのでしょうか? となると、汎用クラスのコンストラクタ引数に値を渡し汎用クラス内でインスタンス変数を使用するってコーディングは完全なNGになりますよね。 HttpServlet継承のサーブレットからインスタンス化されれば、都度個別のメモリが割り当てられると思うのですが・・。 ご存知な方いらっしゃいましたらご教授お願いいたします。 以上

    • ベストアンサー
    • Java
  • 同じ名前の変数…

    数日前からPHPをはじめた者です。 クラス変数(という呼び方が適切かは??)と、その変数に値をセット/ゲットする関数を内包するクラスを作ってみたのですが、それに関してどうもピンと来ない部分があるので質問させてください。 以下がソースです。 class sample{ var $hensu; function set_hensu($str){ $hensu = $str; } function get_hensu(){ return $hensu; } } 上記クラスを使って値のセット/ゲットをしようとしたのですが、結果は×でした。 ファンクション内の変数を、thisで指定するとうまく行きました。 最初に指定した変数と、ファンクション内の変数を同一のものだと認識させるには、ファンクション内でのthis指定の他に方法は無いのでしょうか? もしくは、ファンクション内で書いた変数が新しい変数だと認識させない方法とか…。 無いなら諦めます。よろしくお願いします。 また、直接質問とは関係ないのですが、 どうしてPHPは変数名を書いただけで変数が作られてしまうのでしょう。メリットは何ですか? 分かりづらくて戸惑ってます。

    • ベストアンサー
    • PHP
  • クラスでスレッド作成

    VC++2008Express WIN32APIでRS232Cの通信用クラスを作成しています。 RS232Cの受信用スレッドを作成して 1ポートの受信処理をするようにはできます。 ですが ポート追加するたびにクラスをインスタンス化して受信用スレッドを 作成したいのですが、スレッド作成するには使用する変数などを staticにしないといけないため、クラスを複数インスタンス化できません。 どのような手法でクラスから複数スレッドを作成することができるのでしょうか? 分かりにくい説明ですが、参考になるものなどありましたら、 よろしくお願いします。

  • サーブレットのスレッド管理について

    はじめまして、現在Web Developperを目指し日々サーブレット,JSP, JavaBeansの勉強を続けております。お聞きしたいことは、サーブレット, JavaBeansのスレッド管理です。個人で勉強していると多数のクライアントが一つのサーバーにアクセスするなどという 環境をつくりずらいので、業務経験のあるかたからアドバイスをいただきたいです。 現在スレッドを管理する方法とて,SingleThreadModel インターフェイスの実装かsyncronizedコードを利用できることを知っております。 質問1. 実際のシステムで使われているスレッド管理もこの二つの方法で行われているのでしょうか? 質問2. JDBCよりデータベースに書きこむ部分は、二つのスレッドが同時にDBのデータを書き込まないように、shncronizedコードで囲まなくてはいけないと学びましたが、他の本でDBにはすでに同時アクセス を防ぐ仕組みがあるから、synchronizedコードを書かなくてもよいとかいてありました。どちらが正しいのでしょうか? 質問3. 業務のスレッド管理で主に気をつけなければいけないところは、DBとローカル変数がスレッドセーフになっていることでしょうか、他にも注意するべき点がありますでしょうか? 初心者の質問ですので、的を得ていないところが多々あると思います。それでも少しでも、技術者の方に近づければと思い質問させていただきました。もしよろしければご教授よろしくお願いいたします。

    • ベストアンサー
    • Java

専門家に質問してみよう