【问题标题】:Am I correct in my assumption about synchronized block?我对同步块的假设是否正确?
【发布时间】:2010-05-03 03:27:29
【问题描述】:

我有一个带有同步块的方法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());
     }
  }

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

【问题讨论】:

    标签: java concurrency multithreading synchronized synchronized-block


    【解决方案1】:

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

    注意,如果您要在 this 上使用 Object.wait 而不是调用 Thread.sleep 来延迟,那么锁将被移除(并在继续之前重新获得)。

    【讨论】:

      【解决方案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
      

      【讨论】:

      • 那我就不明白同步块的意义了。
      • @kunjaan 同步确实提供了“互斥”。但极其重要的一点是,互斥只存在于参与 SAME LOCK 的线程之间。任何不参与同一个锁的线程的进度不受影响。因此,执行不需要获取相同锁的代码区域的任何线程(例如在同步块之外打印“SHOUT ...”的行)根本不受锁定的影响。同样的道理,任何试图获取不同对象锁的线程也不受影响(Tom Hawtin 指出)。
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2013-02-01
        • 2012-12-11
        • 2015-12-13
        • 1970-01-01
        • 2018-02-05
        • 2020-04-01
        • 1970-01-01
        • 2011-10-19
        • 1970-01-01
        相关资源
        最近更新 更多