みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

メソッドの処理の同期化

いつもお世話になっています。
メソッド処理の同期化についてなのですが、
いろいろ調べてみたのですが、いまいちうまく実行できません。
ソースを考えてみたのですが、どこがどう悪いのかご指摘お願いできますでしょうか?

以下のクラスがある場合で
public void Add(){
synchronized(this){
System.out.println("待機しています!");
//おそらくここら辺にwait()/notify()処理が来るきがする
//同期中に行わない処理をここに記載する?
}
System.out.println("Addメソッド実行しました"):
}
public void Change(){
synchronized(this) {
//おそらくここら辺にwait()/notify()処理が来るきがする
//同期中に行わない処理をここに記載する?

//一時停止 処理時間をずらすためループを使用
try {
for(int a=0;a<3;a++){
System.out.println("a="+a);
Thread.sleep(10000);
}
}catch (InterruptedException e) {}
System.out.println("Changeメソッド完了です");
}
}

このとき、Add対Change/Add対Addといった形で同期化処理をしたいのですが、どうしてもうまくできません。
仮にThreadを使用して実行してみようとしたのですが、
順番に実行されてしまいます。

したいのが、
1.Addメソッド実行
2・Addメソッド実行
この場合、現状だと
a=0
a=0
a=1
a=1
a=2
a=2 
と表示されてしまうので、
a=0
a=1
a=2
a=0
a=1
a=2 
と表示することはできるのでしょうか?

原因として、wait()/notify()が記載されていないことが影響していると思うのですが。

宜しくお願いします。

投稿日時 - 2009-11-18 16:56:03

QNo.5457969

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

Java Tutorial を参照下さい。
tutorial/essential/concurrency/guardmeth.html
When wait is invoked, the thread releases the lock and suspends execution. At some future time, another thread will acquire the same lock and invoke Object.notifyAll, informing all threads waiting on that lock that something important has happened:

wait, sleep, I/O wait 等でthreadの実行が中断される場合、method synchronized lockは開放され、他のthreadが同一methodの実行を始めます。
wait/sleepが解けて実行が再開される場合には、OSが介入してmethod lockを再設定します。

例えばfile read, record update, rewriteの間lockが必要な場合、method synchronized lockでは対応出来ません。
その場合、file (lock object)単位、record単位等でlockして処理する必要があります。

これらについては次に説明されているはずですので参照下さい。
tutorial/essential/concurrency/highlevel.html 

投稿日時 - 2009-11-19 13:49:49

お礼

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

ninoueさんの、説明してくださった点を調べてみたのですが、
どうもヒットできませんでした。

>例えばfile read, record update, rewriteの間lockが必要な場合、method synchronized lockでは対応出来ません。
>その場合、file (lock object)単位、record単位等でlockして処理する必要があります。
今度、もう一度この点を考えてみます。

後で調べたところ、
Collections.synchronizedListを使用することで無事同期化することができました。

丁寧に説明くださり、ありがとうございました。
また、質問の際には宜しくお願いします。

投稿日時 - 2009-11-24 22:16:33

ANo.1

Addメソッド実行で、Changeメソッドが呼び出されているのでしょうか?
それともChangeメソッドを2度実行した結果ですか?

投稿日時 - 2009-11-19 02:30:02

補足

回答ありがとうございます。
説明ミスでした。
実行したパターンは、Changeメソッドを画面から2回実行した結果です。
試した際、多少の実行時間のずれで、
a=0 ←1回目
a=1 ←1回目 
このあたりで画面から2度目のChangeメソッドが実行される
a=0 ←2回目
a=2 ←1回目
a=1 ←2回目
a=2 ←2回目
といった結果になるので

a=0 ←1回目
a=1 ←1回目
このあたりで画面から2度目のChangeメソッドが実行される
a=2 ←1回目 2回目のChangeメソッド処理は待機中
a=0 ←2回目
a=1 ←2回目
a=2 ←2回目

としたいのですが。

また、1回目・Changeメソッド、
2回目・Addメソッドを実行し、同期化したい場合
何らかのflagをキーにして、同期化するということになるのでしょうか?

宜しくお願いします。

投稿日時 - 2009-11-19 10:08:59