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());
     }
  }

如果我有两个运行此方法的线程,我是否正确假设两个“同步呐喊”总是一个接一个地出现?“同步呐喊”之间不能有其他语句吗?

4

3 回答 3

2

只要this引用相同。如果在两个不同的对象上运行代码,锁将不起作用。

请注意,如果您要使用Object.waitonthis而不是调用Thread.sleep延迟,则锁定将被删除(并在继续之前重新获取)。

于 2010-05-03T03:41:15.217 回答
2

由于打印“SHOUT...”的行不需要锁,它可以出现在任何时候。因此,即使一个线程持有锁,另一个线程也可能进来并打印“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

当两个或多个线程针对同一个实例运行时,SHOUT 可以出现在任何地方,因为它在同步块之外,因此不受保护。“同步的喊叫”将始终严格按顺序出现,没有来自另一个线程的同步喊叫介于两者之间并影响顺序。

于 2010-05-04T01:45:59.767 回答