- PR -

サーブレット、排他制御、マルチスレッドの考慮すべき点

投稿者投稿内容
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2005-12-01 21:51
引用:
この意味というのは、for文のi<v.size()が判断された後に、
Vectorの要素が削除され、v.size()が小さくなった後に、
doSomething(v.get(i)); が実行されてしまう事によって、
例外が発生するという意味なのでしょうか?



そうです。可能性としては低いものですが、ありえないとは言えません。

引用:
スレッドAとスレッドBがあった場合、
Vector v = new Vector();  で生成されたインスタンス変数vは、
スレッドAとスレッドB共通で使用されてしまうのでしょうか?
もしそうだったら全て同期を取らないと恐くて何も出来ない感じがしますが。



複数スレッドから共有されるかはコード次第です。
ローカル変数からしか参照されない場合は共有されないでしょう。
static変数から参照されるのであれば、共有される可能性は高いです。
インスタンス変数であれば、持ち主のインスタンスの使われ方次第でしょう。

同期を取る、という意味がVectorのようにメソッドをすべてsynchronizedとして
宣言するという意味であれば、それはスレッドセーフである保証とはなりません。

先ほどの例では、size()とget()の呼び出しが不可分な処理、つまりatomicに
扱わなければならない処理となるので、その間の処理全体を保護する必要が
あります(ここがクリティカルセクションです)。

Collection Frameworkの基本的なクラス(ArrayListやHashMap等)のメソッドが
synchronizedでない理由はここにあります。Iteratorの処理中に更新があった
場合にはVectorのようなsynchronizedは無意味ですし、いくつかの一連の処理を
atomicに行えないのであれば、実質的にスレッドセーフにはならないのです。

JDK 5.0で追加されたConcurrentHashMap等では、putIfAbsent()などの複合処理を
atomicに行うメソッドを実装すること(他もあります)でこの問題を解決しています。
うる
常連さん
会議室デビュー日: 2005/10/16
投稿数: 41
投稿日時: 2005-12-01 23:30
返答ありがとうございます。

>インスタンス変数であれば、持ち主のインスタンスの使われ方次第でしょう。

この部分がまだ理解不足であります。
同じ処理を複数のスレッドが実行した場合、その処理の中のインスタンス変数はスレッド毎に別々の領域に実態が確保されるのではないかと思っております。
であれば、スレッド間でインスタンス変数の内容は競合しないのではないかと思ってしまうのですが。
あるスレッドで生成したインスタンス変数を引数か何かで渡して、別のスレッドを起動させるというのであれば、インスタンス変数の内容が競合してしまうというのは分かりますけど。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-12-02 02:44
サーブレットのインスタンスが一つしかないということは理解されていますか?
SingleThreadModel を実装していなければサーブレットコンテナはサーブレットのインスタンスを一つしか生成しません。
また、一つインスタンス変数を宣言したらそれはサーブレットのインスタンス一つにつき唯一存在します。
サーブレットのインスタンスが複数のスレッドで共有されれば、インスタンス変数も同じく共有されることになります。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-12-02 12:45
日常生活にたとえるとわかりやすいでしょうか。

インスタンス:道路
インスタンス変数:道路脇のガードレール
スレッド:車

ある車が事故ってガードレールに衝突すると、
他の車からもガードレールが壊れて見えますよね。
それと同じ事です。

引用:

同じ処理を複数のスレッドが実行した場合、その処理の中のインスタンス変数はスレッド毎に別々の領域に実態が確保されるのではないかと思っております。


それはjava.lang.ThreadLocalの話ですね。

henachoco
常連さん
会議室デビュー日: 2005/11/21
投稿数: 29
お住まい・勤務地: 新ハンドル:t_yamo
投稿日時: 2005-12-02 18:09
引用:

うるさんの書き込み (2005-12-01 23:30) より:
同じ処理を複数のスレッドが実行した場合、その処理の中のインスタンス変数はスレッド毎に別々の領域に実態が確保されるのではないかと思っております。



クラス変数やインスタンス変数は全てのスレッドで共有されます(下記参考URL参照)。
……と、いうことが判ればおよその疑問は解消するのではないでしょうか。
で、非SingleThreadModelのServletはひとつのインスタンスとして使いまわされるため、その中のインスタンス変数も複数スレッドで共有されます。

【参考URL】(8.1の始めの4行)
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#22197
うる
常連さん
会議室デビュー日: 2005/10/16
投稿数: 41
投稿日時: 2005-12-02 22:13
どうもまだすっきり理解できません。
何かお勧めの良い参考書とかありませんでしょうか。
JSPやサーブレットの入門書にはここらへんが全然載ってません。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-12-02 22:24
すっきり理解できないのはスレッドですか?サーブレットですか?

スレッドなら、

・Java言語で学ぶデザインパターン入門 マルチスレッド編
・Javaスレッド完全制覇 標準プログラマーライブラリ

この辺を参考にするとスレッドに対する理解が深まると思います。

サーブレットもただのJavaアプリですので、
スレッド等の基本をもっと勉強されてからでも遅くはありません。
#最近はいきなりサーブレットから始める方が多いかも。
masa
大ベテラン
会議室デビュー日: 2005/05/11
投稿数: 108
投稿日時: 2005-12-02 22:44
引用:

うるさんの書き込み (2005-12-02 22:13) より:
どうもまだすっきり理解できません。


おそらくスレッドとServlet仕様がごっちゃになって混乱されているのだ
と思います。
Servletは一つのインスタンスが複数のスレッドで共有されます。これは
Servletの仕様です。
インスタンス変数が共有されてしまうのは、Servletが一つのインスタン
スを複数のスレッドで使いまわす形で実装されていることが原因です。
(SingleThreadModelというキーワードは興味があったら後々勉強してみ
てください。)

ちなみにスレッド関連の本としては
・Java言語で学ぶデザインパターン入門 マルチスレッド編
を私もお勧めします。

スキルアップ/キャリアアップ(JOB@IT)