3

少し混乱しています。以下のコードを見てください。

public class ThreadDemo {
  //non-static synchronized method
  synchronized void a(){
   actBusy();
  }

  //static synchronized method
  static synchronized void b(){
    actBusy();
  }

  //static method
  static void actBusy(){
    try{
      Thread.sleep(1000);
    }
    catch(InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args){
    final ThreadDemo x = new ThreadDemo();
    final ThreadDemo y = new ThreadDemo();
    Runnable runnable = new Runnable() {
      public void run() {
         int option = (int) (Math.random() * 4);
         switch (option){
           case 0: x.a();
             break;
           case 1: x.b();
             break;
           case 2: y.b();
             break;
           case 3: y.b();
             break;
         }
      }
    }   ;
    Thread t1 = new Thread(runnable);
    Thread t2 = new Thread(runnable);
    t1.start();
    t2.start();
  }
}

このシーケンスの呼び出しが可能であることは確かです。

x.a() //in Thread-1
y.b() //in Thread-2

まだ少し混乱していますが、静的メソッドであるメソッドx.a()も呼び出すことが簡単にわかります。actBusy()メソッドb()は、非同期静的メソッドを呼び出す静的同期メソッドです。スレッド 2 がクラス レベルのロックを取得するとactBusy()、スレッド 1 からの呼び出しがブロックされないのはなぜですか?

スレッドがクラスレベルのロックを取得した場合、そのクラスの他の同期されていない静的メソッドは、他のメソッド(インスタンスメソッド)から呼び出されるために開いたままになります。なんで?

4

4 に答える 4

4

actBusy()それでは、Thread-1 からの呼び出しがブロックされないのはなぜですか?

actBusyメソッドが同期されていないためです。クラス レベルのロックを取得した場合でも、非同期の静的メソッドを呼び出すことができます。

メソッドをそのままマークするポイントは、synchronizedロックを有効にすることです。これらのロックの対象となるのは、同期済みとして宣言されたメソッドのみです。したがって、ロックを取得した場合 (クラス レベルのロックを想定)、どのnon-synchronizedメソッドも以前と同じように動作し、ロックが取得されたことを認識しません。これにより、ブロックする必要があるメソッドとブロックしないメソッドを決定できます。

于 2013-08-09T08:36:09.080 に答える
1

ロック オブジェクトは階層的ではありません。したがって、クラス自体のロックを取得しても、クラスのインスタンスのロックに取って代わることはありません。これらは別個のロック オブジェクトであり、まったく同じオブジェクトをロックしようとするコードのみをブロックします。

したがって、スレッドが静的同期メソッドに入った場合、ブロックされるスレッドは、同じクラスで静的同期メソッドに入ろうとしているスレッドだけです。非静的同期メソッドに入ろうとしているだけのスレッドは影響を受けません。スレッドは、同じオブジェクト インスタンスで非静的同期メソッドに入ろうとしているスレッドと競合するだけです。

以下のコメントについて-マークされた静的メソッドのみsynchronizedがクラスレベルのロックの対象となります。他の静的メソッドをブロックする場合は、それらもマークする必要がありますsynchronized

これはなぜですか?1つがsynchronized. プログラマーは、スレッドの安全性を確保するためにどのメソッドを同期する必要があるかを知っていると想定されています。

于 2013-08-09T08:39:58.020 に答える