プロが教えるわが家の防犯対策術!

Javaの本を買って読んでいます。
その中の「スレッド」のカテゴリーの「状態遷移」のところの「synchronized」の部分に、こう書かれています。

--------------------------
・・・・・・
なお、sleepメソッドでスリープ状態(実行不可能状態)になったスレッドはロックを保持したまま開放しません。
そのため、ロックを取得できないで待たされるスレッドも実行不可能状態へ移行させられます。

--------------------------
これは、Synchronized指定されたメソッド(同期メソッド)の部分で出てきた文章でして、
私は、こう解釈しました。

→ 例えば、同じオブジェクトの参照を引数とするスレッドが3つあり、その中の1つが『実行中』状態にある(仮に t1 とする)として(つまり残り2つ( t2 t3 )は『実行可能状態(プール)』にある。)、
実行中の t1 がsleep()メソッドで『実行不可能状態』になった場合、 『実行可能状態』にあった、t2 t3 も『実行不可能状態』へ移行する事になる。

間違っていますか?
もし、この解釈が正しければ、こうなりますよね?

t1・・・・・・・『実行中』 → 『実行不可能状態』
t2 t3・・・『実行可能状態』 → 『実行不可能状態』

ところが、状態遷移の5つの状態の図を見ると、
『実行可能状態』 から 『実行不可能状態』 へは、矢印→が書かれておりません。(逆向きの矢印がありますが。)

どういう意味でしょうか。
java初心者ですが、
解りやすく教えて頂けると助かります。
宜しくお願い致します。

A 回答 (3件)

添付失敗してしもうた。

「スレッドの状態遷移について。。。」の回答画像3
    • good
    • 0

Wikipediaから図を持ってきて添付してみました。


Blocked: 実行不可能状態(ブロック、スリープ)
Waiting: 実行可能状態(待機状態)
Running: 実行中
と対応していると思います。

t1がm1の中でsleepが実行されると、
スレッドは実行を停止ます。
これが「実行不可能状態」に対応しているはずです。
sleepは指定時間の間何もしない(実行を停止)で、
指定時間が過ぎると実行を再開します。
この段階で「実行可能状態」に移り、「実行中」に移ります。

t1はまだm1の中なのでここまではロックを保持しているので、
他のスレッドt2などはまだm1に入れません。
この段階でt2がm1に入ろうとすればt2は実行不可能状態になります。

t1がm1を終了するとロックを外すので、
t2がm1に入れるようになります。
t2がm1の入口で待っていた(実行不可能状態)とすると、
このときt2は実行可能状態に移り、実行中に移ればm1に入ります。

参考URL:http://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD% …
    • good
    • 0

簡単に言うと、synchronized宣言されたメソッドは、同時にひとつのスレッドでしか実行されません。


synchronized宣言されたメソッドm1があるスレッドt1で実行されている最中は、
他のスレッドt2はそのメソッドm1を実行しようとすると入ることができず待たされます。
t1がm1を終えるとt2は待ちを解除されm1に入ることができます。

ところがt1がm1を実行中にsleepしてしまうと、
sleepが終わるまでt1はm1を終了しないので、
m1に入ろうとしていたスレッドt2はずっと待たされます。
t1がsleepを終えてm1を抜けるまで待たされることになります。

という意味のはずです。

なお、スレッドt2はm1を実行しようとしたら待たされるのであって、
他の関係ない処理は継続して実行できます。
なのでt1が止まってしまったからt2も無条件に止まるということはありません。

ちなみに、ひとつのクラスC(のインスタンスi)内の2つのメソッドm1, m2がどちらもsynchronized宣言されていると、
あるスレッドt1がm1を実行中のとき、別なスレッドt2はm1に入れないだけでなく、m2にも入れません。
これはm1, m2はどちらも共通のオブジェクトiで排他処理(ロック)されているからです。
一方でスレッドt2はsynchronized宣言されていないC(i)内のメソッドm3には自由に入れます。
何のオブジェクトに関しても排他処理されていないからです。
    • good
    • 0
この回答へのお礼

ご丁寧な文面、付随事項、解りやすい解説をありがとうございます。

ちょっと確認の意味もこめての質問させてください。

>ところがt1がm1を実行中にsleepしてしまうと、
>sleepが終わるまでt1はm1を終了しないので、・・・

そもそもsleepは『実行不可能状態』にいるわけですよね?
という事は、t1がsleepを終了すると、『実行中』には戻れないから、
ロックだけを開放して『実行不可能状態』に待機しているという事ですか?
で、t2かt3のどちらかがsynchronizedスレッドに入っていく、
という事でいいのでしょうか?
つまり、t2もt3も『実行可能状態』に居続ける、という事でいいのでしょうか。

何度もすみません、宜しくお願い致します。

お礼日時:2012/07/13 21:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!