- - PR -
サーブレット、排他制御、マルチスレッドの考慮すべき点
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-01 21:51
そうです。可能性としては低いものですが、ありえないとは言えません。
複数スレッドから共有されるかはコード次第です。 ローカル変数からしか参照されない場合は共有されないでしょう。 static変数から参照されるのであれば、共有される可能性は高いです。 インスタンス変数であれば、持ち主のインスタンスの使われ方次第でしょう。 同期を取る、という意味がVectorのようにメソッドをすべてsynchronizedとして 宣言するという意味であれば、それはスレッドセーフである保証とはなりません。 先ほどの例では、size()とget()の呼び出しが不可分な処理、つまりatomicに 扱わなければならない処理となるので、その間の処理全体を保護する必要が あります(ここがクリティカルセクションです)。 Collection Frameworkの基本的なクラス(ArrayListやHashMap等)のメソッドが synchronizedでない理由はここにあります。Iteratorの処理中に更新があった 場合にはVectorのようなsynchronizedは無意味ですし、いくつかの一連の処理を atomicに行えないのであれば、実質的にスレッドセーフにはならないのです。 JDK 5.0で追加されたConcurrentHashMap等では、putIfAbsent()などの複合処理を atomicに行うメソッドを実装すること(他もあります)でこの問題を解決しています。 | ||||||||
|
投稿日時: 2005-12-01 23:30
返答ありがとうございます。
>インスタンス変数であれば、持ち主のインスタンスの使われ方次第でしょう。 この部分がまだ理解不足であります。 同じ処理を複数のスレッドが実行した場合、その処理の中のインスタンス変数はスレッド毎に別々の領域に実態が確保されるのではないかと思っております。 であれば、スレッド間でインスタンス変数の内容は競合しないのではないかと思ってしまうのですが。 あるスレッドで生成したインスタンス変数を引数か何かで渡して、別のスレッドを起動させるというのであれば、インスタンス変数の内容が競合してしまうというのは分かりますけど。 | ||||||||
|
投稿日時: 2005-12-02 02:44
サーブレットのインスタンスが一つしかないということは理解されていますか?
SingleThreadModel を実装していなければサーブレットコンテナはサーブレットのインスタンスを一つしか生成しません。 また、一つインスタンス変数を宣言したらそれはサーブレットのインスタンス一つにつき唯一存在します。 サーブレットのインスタンスが複数のスレッドで共有されれば、インスタンス変数も同じく共有されることになります。 | ||||||||
|
投稿日時: 2005-12-02 12:45
日常生活にたとえるとわかりやすいでしょうか。
インスタンス:道路 インスタンス変数:道路脇のガードレール スレッド:車 ある車が事故ってガードレールに衝突すると、 他の車からもガードレールが壊れて見えますよね。 それと同じ事です。
それはjava.lang.ThreadLocalの話ですね。 | ||||||||
|
投稿日時: 2005-12-02 18:09
クラス変数やインスタンス変数は全てのスレッドで共有されます(下記参考URL参照)。 ……と、いうことが判ればおよその疑問は解消するのではないでしょうか。 で、非SingleThreadModelのServletはひとつのインスタンスとして使いまわされるため、その中のインスタンス変数も複数スレッドで共有されます。 【参考URL】(8.1の始めの4行) http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#22197 | ||||||||
|
投稿日時: 2005-12-02 22:13
どうもまだすっきり理解できません。
何かお勧めの良い参考書とかありませんでしょうか。 JSPやサーブレットの入門書にはここらへんが全然載ってません。 | ||||||||
|
投稿日時: 2005-12-02 22:24
すっきり理解できないのはスレッドですか?サーブレットですか?
スレッドなら、 ・Java言語で学ぶデザインパターン入門 マルチスレッド編 ・Javaスレッド完全制覇 標準プログラマーライブラリ この辺を参考にするとスレッドに対する理解が深まると思います。 サーブレットもただのJavaアプリですので、 スレッド等の基本をもっと勉強されてからでも遅くはありません。 #最近はいきなりサーブレットから始める方が多いかも。 | ||||||||
|
投稿日時: 2005-12-02 22:44
おそらくスレッドとServlet仕様がごっちゃになって混乱されているのだ と思います。 Servletは一つのインスタンスが複数のスレッドで共有されます。これは Servletの仕様です。 インスタンス変数が共有されてしまうのは、Servletが一つのインスタン スを複数のスレッドで使いまわす形で実装されていることが原因です。 (SingleThreadModelというキーワードは興味があったら後々勉強してみ てください。) ちなみにスレッド関連の本としては ・Java言語で学ぶデザインパターン入門 マルチスレッド編 を私もお勧めします。 |