1

同期されたブロックを持つメソッドのshout()があります。

  private void shout(){
    System.out.println("SHOUT " + Thread.currentThread().getName());
    synchronized(this){
      System.out.println("Synchronized Shout"  + Thread.currentThread().getName());
      try {
        Thread.sleep(50);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Synchronized Shout"  + Thread.currentThread().getName());
     }
  }

このメソッドを実行するスレッドが 2 つある場合、2 つの「同期されたシャウト」が常に次々に表示されると仮定して正しいでしょうか? 「シンクロナイズド シャウト」の間に他のステートメントはありませんか?

4

3 に答える 3

2

this参照が同じである限り。2 つの異なるオブジェクトでコードを実行すると、ロックは無効になります。

delayを呼び出す代わりにObject.waitonを使用すると、ロックが解除されます (次に進む前に再取得されます)。thisThread.sleep

于 2010-05-03T03:41:15.217 に答える
2

"SHOUT..." を出力する行はロックを必要としないため、いつでも表示できます。したがって、1 つのスレッドがロックを保持している場合でも、別のスレッドが入ってきて「SHOUT...」を出力することがあります。

次のコードは、インターリーブを示しています。

public class Interleave {
  public static void main(String[] args) throws Throwable {
    Task task = new Task();
    Thread t1 = new Thread(task);
    Thread t2 = new Thread(task);
    t1.start();
    Thread.sleep(25);
    t2.start();
  }

  private static class Task implements Runnable {
    public void run() {
      shout();
    }

    private void shout() {
      System.out.println("SHOUT " + Thread.currentThread().getName());
      synchronized (this) {
        System.out.println("Synchronized Shout "  + Thread.currentThread().getName());
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("Synchronized Shout "  + Thread.currentThread().getName());
      }
    }
  }
}

プリントアウトします

SHOUT Thread-0
Synchronized Shout Thread-0
SHOUT Thread-1
Synchronized Shout Thread-0
Synchronized Shout Thread-1
Synchronized Shout Thread-1
于 2010-05-03T04:17:25.050 に答える
0

2 つ以上のスレッドが同じインスタンスに対して実行されている場合、SHOUT は同期ブロックの外側にあり、保護されていないため、どこにでも現れる可能性があります。「同期されたシャウト」は常に厳密に順番に表示され、別のスレッドからの同期されたシャウトが間に入って順序に影響を与えることはありません。

于 2010-05-04T01:45:59.767 に答える