Next: 12.5 スタティックな同期メソッド
Up: 12 同期処理
Previous: 12.3 synchronizedブロック
メソッドで同期を取る場合には,
method名の前にsynchronizedを付ける.
そのようなメソッドはsynchronizedメソッド
同期メソッドと呼ぶ.
あるインスタンスに対するsynchronizedメソッドの実行は,一度に一つのスレッ
ドでしかできない.synchronizedが付いていないメソッドは二つ
以上のスレッドで同時に実行が可能.
あるインスタンスに対してsynchronizedメソッドが実行されると,そのインス
タンスに対して他のsynchronizedメソッドが実行できない状況は相互排他
(mutual exclusion) といわれる.相互排他の機構は,あるスレッドがそのイン
スタンスに対するロック(lock)を取得し,必要な処理の実行が終わったらば
そのロックを開放するということ実現される.
あるクラスの二つのメソッドA,Bのそれぞれに
synchronizedがついているとした場合,
スレッドXがあるインスタンスiに対して,
メソッドAを実行している時に,
別のスレッドYが同じインスタンスi
に対してメソッドBを実行しようとしても
それは実行できない.
インスタンスが複数ある場合に,別のインスタンスに対するsynchronizedメソッ
ドは複数同時に実行することが可能である.
synchronized文により同期をとる場合には,そのオブジェクトへのアクセスをそ
のオブジェクトを扱う場所ごとに記述する必要があり,クライアント側同期と呼
ばれているが,synchronizedメソッドのようにそのオブジェクトへのアクセスを
行うメソッド自体が同期されるという場合には,クライアント側で同期文を使う
必要がないため,サーバ側同期(server-side synchronization)と呼ばれ
たりする.
// synchronize3.java
class synchronize3
{
public static void main(String args[])
{
Shared shared = new Shared();
CustomThread6 thread1 =
new CustomThread6(shared, "one");
CustomThread6 thread2 =
new CustomThread6(shared, "two");
CustomThread6 thread3 =
new CustomThread6(shared, "three");
CustomThread6 thread4 =
new CustomThread6(shared, "four");
try {
thread1.join();
thread2.join();
thread3.join();
thread4.join();
} catch(InterruptedException e) {}
}
}
class CustomThread6 extends Thread
{
Shared shared;
public
CustomThread6(Shared shared, String string)
{
super(string);
this.shared = shared;
start();
}
public void run() {
shared.doWork(
Thread.currentThread().getName());
}
}
class Shared
{
synchronized void doWork(String string){
System.out.println("Starting " +
string);
try {
Thread.sleep((long)
(Math.random() * 500));
} catch (InterruptedException e) {}
System.out.println("Ending " + string);
}
}
これを実行すると,
% java synchronize3
Starting one
Ending one
Starting two
Ending two
Starting three
Ending three
Starting four
Ending four
generated through LaTeX2HTML. M.Inaba 平成18年5月7日