- - PR -
サーブレット、排他制御、マルチスレッドの考慮すべき点
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-03 07:42
返答ありがとうございました。
「Java言語で学ぶデザインパターン入門 マルチスレッド編」 早速注文しました。 ちょっと高かったですが。 | ||||||||||||
|
投稿日時: 2005-12-03 14:24
下のコードは,メンバ変数valueの値をローカル変数にコピーして1増やす。
そして,適当な時間スリープした後に,value + 1した結果がローカル変数の 値と等しいか比べてメッセージを出すコードです。 これを動かすと「駄目じゃん」っていうメッセージがボコボコ 出てくる。
Servletも同じように,1つのインスタンスが複数のスレッドから参照されるので, メンバ変数を使うなら,かなり気をつけないといけない。 (というか個人的には怖くて普通使えない) | ||||||||||||
|
投稿日時: 2005-12-03 23:32
サーブレットでのマルチスレッドですが、
このような認識で良いのでしょうか? この認識で合っていれば、すっきりするのですが。 ----------------------------------------- サーブレットの処理を行うクラス public class Hoge extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{ //サーブレット処理 } } ----------------------------------------- サーブレットコンテナ側での呼び出しイメージ ブラウザ1とブラウザ2からアクセスがあった場合 req1,res1はブラウザ1に対応 req2,res2はブラウザ2に対応 Hoge hoge = new Hoge; new ServletThread(hoge, req1, res1).start(); new ServletThread(hoge, req2, res2).start(); ServletThreadは適当な名前で作りました。 ServletThread内のrunメソッドで、 hoge.doGet(req, res);が実行される。 | ||||||||||||
|
投稿日時: 2005-12-04 01:38
>うるさん
大雑把に言えば、そんな感じで差し支えないと思います。 実際にはもっと複雑な手法で構成されていますが、 サーブレット利用者側からすると、 うるさんのスレッドに対する認識で充分だと思います。 | ||||||||||||
|
投稿日時: 2005-12-04 08:16
先ほどの自分の例で確認して頂きたいところがあるのですが、
引数やメソッド内で宣言されているオート変数のint aは、 スレッド間で競合が起こらないと思うのですが、この認識で問題ありませんでしょうか。 newされたHoge2クラスも、Hoge2クラス内でstaticなプロパティが無ければ、スレッド間での競合は起こらないと思うのですが、この認識で良いのでしょうか? スレッド内でnewされたクラスのインスタンスは別々に確保されるという認識です。 | ||||||||||||
|
投稿日時: 2005-12-04 09:52
自分でスレッド起こして競合するような状況を作らない限り大丈夫です。
| ||||||||||||
|
投稿日時: 2005-12-04 12:26
Kazukiさん回答ありがとうございます。
それでも、ArrayList等を使う場合は、synchronizedListを使わないとだめなのですよね。 ArrayListがstaticなプロパティを使っているから同期を取らないとダメなのでしょうか? そういう事なら納得できますが、それ以外の要因で同期を取らなくてはいけないのでしたら、まだどうも納得がでません。 スレッド内でnewされたクラスのインスタンスは別々に確保されるという考えが崩れてしまいます。
| ||||||||||||
|
投稿日時: 2005-12-04 13:20
ArrayListは「クラス単位」ではスレッドセーフです。同一インスタンスを 複数スレッドで共有しない限り、明示的な同期化は必要ありません。 内部にstaticな変数があったとしても、うまく扱ってるはずです。
このarrayListに代入されたインスタンスを他のスレッドと共有させたりせず、 リクエスト処理の完了時に破棄(ガベージコレクトの対象となる)される場合は 特に同期化を考える必要はないです。 Collections.synchronizedList()は、Vector等のメソッド宣言のsynchronized だけでは不十分なのと同じ理由で不十分です。多くの場合は、自分で排他制御を 行わないと無意味なモニタの獲得が発生するだけでしょう。 私は、CollectionsのsynchronizedList()系のメソッドをVectorなどの旧仕様の コレクションの同期化と互換性を持たせる目的でしかないと捉えています。 |