next up previous
Next: 12.5 スタティックな同期メソッド Up: 12 同期処理 Previous: 12.3 synchronizedブロック

12.4 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日