|
なんとなく、後回しにしてきたマルチスレッドプログラミングなんですが、SWTの勉強などGUIプログラミングをやってると、どうしても知識が必要だなって思えてきまして、ちょっと勉強中です。 まだ全然わかってないんですが、いろいろメモ。 InterruptedException? が発生するタイミング †途中。 synchronizedにすることで、どこが同期化されるのか。 †下のクラスはsynchronizedのメソッドとそうでないメソッドがあります。 public class Data {
public synchronized void syncExecute() {
System.out.println("syncExecute実行中......");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("syncExecute実行終了");
}
public void execute() {
System.out.println("execute実行");
}
}
それぞれのメソッドを呼び出すスレッドがあるとします。 class SyncThread extends Thread {
private Data data;
public SyncThread(Data data) {
this.data = data;
}
public void run() {
data.syncExecute();
}
}
class TestThread extends Thread {
private Data data;
public TestThread(Data data) {
this.data = data;
}
public void run() {
data.execute();
}
}
このスレッドを同時に実行すると、 public class ThreadTest{
public static void main(String[] args) {
System.out.println("Start.");
Data data = new Data();
new SyncThread(data).start();
new TestThread(data).start();
System.out.println("End.");
}
}
結果は Start. End. syncExecute実行中...... execute実行 <- syncExecute実行中にも実行されている syncExecute実行終了 ってなって、synchronized なメソッドを実行中にもその他のメソッドは実行されています。ってことは別のスレッドがあるインスタンスのモニタを取得している時も、「synchronizedでない」他のメソッドは実行されるって事なんですね。 んでは、先ほどのメソッドを public void execute() {
-> public synchronized void execute() {
に変更すると、 Start. End. syncExecute実行中...... syncExecute実行終了 execute実行 となり、同時には実行されていないことがわかります。つまり、ある一時点で、ひとつのインスタンスに対して実行されているsynchronized メソッドはひとつであるということが分かります*1。さらにThread#sleep()してもモニタは解放しないということも分かりました*2。 まとめると、 synchronizedメソッドはモニタをとらないと実行できない。 ってことですね*3。なんだか当たり前の結論に行き着きました。。 Thread#sleep()とObject#wait() †上の結論より、 Thread#sleep() したときにモニタは解放しない Object#wait() したときにモニタは解放される となります。 そもそもThread#sleep()はモニタを取らなくても実行可能なので、モニタの解放も何もないわけです。またObject#wait()を呼ぶスレッドはそのインスタンスのモニタを取得している必要がありますが、wait()を呼び出した瞬間そのスレッドはダンマリになるわけで、そこでモニタを解放しないと、誰もそのインスタンスのnotfyAll()を呼べないことになります。 この記事は
現在のアクセス:9277 |