【问题标题】:'Implicit' synchronization in java?java中的“隐式”同步?
【发布时间】:2011-04-01 00:31:57
【问题描述】:

当我有类似的方法时

public void unsynchronizedMethod(){
  callSynchronizedMethod();
  //dosomestuff after this line
}

是不是所有的内容,在unsynchronizedMethod()-Method中调用callSynchronizedMethod()后,都是隐式同步的?

【问题讨论】:

    标签: java synchronization


    【解决方案1】:

    没有。锁在callSynchronizedMethod()结束时释放。

    【讨论】:

      【解决方案2】:

      同步的定义很简单:

      • 对于synchronized 方法:在该方法的执行中
      • 对于synchronized 块:在该块的执行中

      以下是Java 语言规范第 3 版的相关摘录:

      JLS 14.19 The synchronized Statement

      synchronized 声明:

      1. 代表执行线程获取互斥锁,
      2. 执行一个块,
      3. 然后释放锁。

      当执行线程拥有锁时,没有其他线程可以获取锁。

      synchronized 方法在语义上与应用于整个方法的synchronized 语句相同(§JLS 8.4.3.6。锁是从this(如果它是实例方法)或与关联的Class 对象获得的方法的类(如果它是static 方法;您不能在static 上下文中引用this)。

      所以要回答原来的问题,给定这个 sn-p:

      public void unsynchronizedMethod(){
        callSynchronizedMethod();
      
        doSomeUnsynchronizedStuff(); // no "implicit synchronization" here
      }
      

      请注意,这是设计使然:您应始终努力将同步最小化到仅关键部分。在这些关键部分之外,早期同步不会产生任何挥之不去的影响。

      另见

      • 有效的 Java 第 2 版,第 67 条:避免过度同步

      相关问题

      【讨论】:

        【解决方案3】:

        不,不是。

        同步意味着一次只有一个线程会执行代码。

        但在callSynchronizedMethod() 之后,线程可以同时以不同的顺序再次运行代码。

        【讨论】:

          【解决方案4】:

          不,不会有隐式同步。同步在块或函数范围内工作。同步块之外的任何内容都不会同步。

          以下示例代码显示了这一点。如果同步的方法总是打印 0。

          class example extends Thread{
             //Global value updated by the example threads
             public static volatile int value= 0;
              public void run(){
              while(true)//run forever
                 unsynchMethod();
          
             }
             public void unsynchMethod(){
               synchronizedMethod();
              //Count value up and then back down to 0
              for(int i =0; i < 20000;++i)
                 value++;//reads increments and updates value (3 steps)
              for(int i = 0; i < 20000;++i)
                 value--;//reads decrements and updates value (3 steps)
                //Print value 
                System.out.println(value);
             }
             //Classlevel synchronized function
             public static synchronized void synchronizedMethod(){
                //not important
             }
             public static void main(String... args){
              example a = new example();
              example b = new example();
              a.start();
              b.start();
             }
          
          }
          

          如果同步,我的结果应该是 0:

          4463
          6539
          -313
          -2401
          -3012
          ...
          

          【讨论】:

            猜你喜欢
            • 2019-08-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多