重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

http://www.stackasterisk.jp/tech/java/sjcp05_15. …

↑の問題の解答で

”あるスレッドが「9行目~11行目、15行目~19行目」までの処理を実行している間に、
「23行目~25行目」の処理を他のスレッドが実行することはありえるのです。”

とあるのですが
removeObj1メソッドとremoveObj2メソッドは
synchronizedメソッドだと思うので
removeObj1メソッドとremoveObj2メソッドが
同時に実行される事はないと思ったのですが
synchronizedメソッドないにsynchronizedブロックが
あるとブロック単位でのロックになるのでしょうか?

addObj1が実行されているときに
removeObj2が実行されるのはわかるのですが、

”ArrayListのremove( )メソッドを呼ぶときに
IndexOutOgBoundsExceptionが発生する可能性があるので
答えはC, Dになります。

と言うのがどうもわかりません。”


宜しくお願いします。

A 回答 (6件)

質問者さんは、理解できていると思います。



確かにあの図はおかしいと思います。

図の中で「synchronized(lockObj1)があるから待たされる」と言っていますが、
lockObj1はstaticではないため、「synchronized(lockObj1)があるから待たされる」ためには、
どのスレッドも同じMonitor オブジェクトを参照しなければなりません。

ということは、メソッドのsynchornizedで引っかかります。
つまり、きちんと処理されることになります。


ただ、図とは違ってきますがスレッドがそれぞれ別のMonitor オブジェクトを
参照していたとすると、待ちは一切発生しないので解答のとおり例外が発生する
可能性があります。

*lockObj1、lockObj2がstaticだったら、図の通りになったかな。

この回答への補足

ご返答ありがとうございます。

そうですか、、やっぱりあの図がおかしいですか。。
おかげ様で もやもやが取れました。(^^

すいません、今一度確認させて下さい。

> *lockObj1、lockObj2がstaticだったら、図の通りになったかな。

どのスレッドも同じMonitorオブジェクトを参照している場合
lockObj1、lockObj2がstaticだったとしても
synchornizedメソッドで排他がかかるので
図のようにremoveObj1メソッドとremoveObj2メソッドが
同時に実行される事はないと考えて宜しいでしょうか?

補足日時:2004/08/17 18:26
    • good
    • 0

そして、No5を補足すると


###No5##の内容の一部
>ただ、図とは違ってきますがスレッドがそれぞれ別のMonitor オブジェクトを
>参照していたとすると、待ちは一切発生しないので解答のとおり例外が発生する
>可能性があります。

とありますが。
具体的にどんな時に
例外が発生する可能性があるかという説明については、

私のNo2の回答の
↓の部分以降を読んでもらえればわかります。
##No2の回答の一部
if( i < list.size() ) {

という
チェック処理がありますが。
####
    • good
    • 0
この回答へのお礼

度々&詳細な回答をありがとうございました。
おかげ様でスレッドの理解度が深まったと
感じております。

お礼日時:2004/08/17 18:30

>removeObj1メソッドとremoveObj2メソッドは


>synchronizedメソッドだと思うので
>removeObj1メソッドとremoveObj2メソッドが
>同時に実行される事はないと思ったのですが


「メソッドをsynchronizedにしたのに同期化されないのはなぜ?」
という過去の質問の、
「質問文自体」と「No.5の回答」を参照。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=749910


(http://www.gimlay.org/~javafaq/S021.html
「メソッドに付ける synchronized って何ですか?」)

この回答への補足

ご返答ありがとうございます。

皆様にご教授頂いて
排他の範囲はメソッドではなくインスタンスなので
インスタンスが異なれば待たされずに同時に実行できる。
、、という事で理解できそうな気がしたのですが
自分の中でどうしても【解説】の上の方の絵とマッチしません。

th1とth2でクラスMonitorを別インスタンスとしてスレッドを実行した場合、
インスタンスが異なるのでth1で実行中のメソッドもth2で実行できると
思っているのですが、それはあっていますでしょうか?
解説の絵だとthisもlockObj1,lockObj2も同じものを
指している(?)ので同一インスタンスですよね?
それでいてsynchronizedメソッド(this)で排他が
かかっている中のsynchronizedブロックが同時に実行できるというというのが
どーもよく解りません。(^^;

synchronizedメソッドでなければ自分の中では解説の絵ともマッチするのですが。。
なにか見かたがおかしいのでしょうか?


なかなか難しいですが、なんとかスレッドを理解したいと考えております。
今一度、アドバイス頂ければと存じます。

宜しくお願い致します。

補足日時:2004/08/17 11:07
    • good
    • 0

<<<<訂正>>>>>



誤)

しかし、
lockObj1
をロックしている
removeObj2
は上記の2つとは、
独立的、並列的に実行させることは
可能です。

正)

しかし、
lockObj2
をロックしている
removeObj2
は上記の2つとは、
独立的、並列的に実行させることは
可能です。


#######################3

lockObj1 → lockObj2

この回答への補足

ご返答ありがとうございます。
もうちょっとで解りそうな気がするのですが
No4.の方の補足に新たに質問を書き込ませて頂きました。
もしよろしければアドバイス頂ければと思います。
宜しくお願い致します。

補足日時:2004/08/17 11:05
    • good
    • 0

一般的にロックはリソースに対して取得するものです。


DBの行、ページ、や
ファイルシステム上のファイル、
メモリ上のあるオブジェクトなど。

javaで
synchronized(
ブロックのなかで、
()のなかにロックしたいオブジェクトを
与えてます。

ちなみに、

synchronized void foo() {
}
のような場合は

void foo() {
synchronized(this) {
}
}

にほぼ、同じです。


lockObj1 と
lockObj2 は
ロックの制御だけのために
使われているようです。

addObj1

removeObj1
はともに
synchronized(lockObj1){
の中で
listにアクセスしているので、
addObj1

removeObj1
が同時に
listにアクセスすることはありません。

しかし、
lockObj1
をロックしている
removeObj2
は上記の2つとは、
独立的、並列的に実行させることは
可能です。

if( i < list.size() ) {

という
チェック処理がありますが。

removeObj1とremoveObj2
の両方がこのチェック処理を
通過して、ifの中にはいった時、
removeObj1が、remove(i)
を実行した結果たまたま、
list.size() - 1 が
i より、小さくなった時
removeObj2が
remove(i)
を実行すると、
IndexOutOgBoundsException
が発生します。

removeObj1とremoveObj2のremove(i)
を実行する順番が逆であれば、
removeObj1が
remove(i)
を実行したところで、
IndexOutOgBoundsException
が発生します。

理解のポイントとしては、
同じリソースをロックしている
もの同士(スレッド)だけが、
互いに排他制御をするという
ことです。

syncronizedで、そのスレッドが
どのリソースのロックを取得しようと
しているかに注目してください。


以上
    • good
    • 0

listは、クラス変数なので、複数のインスタンスから参照(共有)されます。


あるインスタンスがremoveObj1()を起動すると同時に、別のインスタンスがremoveObj2()を起動した場合に、競合の恐れがあります

――という事では。

この回答への補足

ご返答ありがとうございます。
もうちょっとで解りそうな気がするのですが
No4.の方の補足に新たに質問を書き込ませて頂きました。
もしよろしければアドバイス頂ければと思います。
宜しくお願い致します。

補足日時:2004/08/17 11:02
    • good
    • 0

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