同步方法与块的性能

时间:2013-05-06 13:27:18

标签: java performance synchronized

我有一个类需要同步所有方法(没有静态方法)。其中一种方法将每50毫秒调用一次。

我想知道将synchronized关键字放在哪里具有最短的执行时间?

即。关于执行时间的2个选项之间是否有任何差异?

选项1(同步方法)

public class MyNativeObject{

     private boolean released = false;

     public synchronized String read(){
         if(released) return null;
         return Read(); 
     }

     public synchronized void release(){
         if(released) return;
         released = true;
         Release();
     }
     private native String Read();
     private native void Release();
}

选项2(同步块)

public class MyNativeObject{

     private Boolean released = false;

     public String read(){
         synchronized(released){
             if(released) return null;
             return Read(); 
         }
     }

     public void release(){
         synchronized(released){
             if(released) return;
             released = true;
             Release();
         }
     }
     private native String Read();
     private native void Release();
}

3 个答案:

答案 0 :(得分:6)

选项#1工作,几乎是完美的,除了同步对象对外部可见,如果可能应该避免。

选项#2是非常危险的,可能是错误的,因为您同步的对象发生了更改(当releasedBoolean.TRUE更改为Boolean.FALSE时,它将在另一个对象上同步!

选项#3将是:

public class MyNativeObject{

     private boolean released = false;
     private final Object monitor = new Object[0];

     public String read(){
         synchronized(monitor){
             if(released) return null;
             return Read(); 
         }
     }

     public void release(){
         synchronized(monitor){
             if(released) return;
             released = true;
             Release();
         }
     }
     private native String Read();
     private native void Release();
}

我们的想法是使用一个对象作为无法从代码外部访问的监视器(请参阅this page以了解我使用new Object[0]代替更常见的new Object()) 。这样,任何其他同步都不会干扰您的同步。

答案 1 :(得分:6)

你不能有同步的课程。

正如Joachim指出的那样,选项2是错误的,因为你锁定a)一个变化的领域和b)一个全局对象。

同步方法不仅是唯一有效的方法,而且是最简单的方法,我将使用它。

典型的锁定需要大约50纳秒,所以如果你每50,000,000纳秒调用这些方法,它就不太可能产生任何差异。

public class MyNativeObject{

     private boolean released = false;

     public synchronized String read(){
         return released ? null : Read(); 
     }

     public synchronized void release(){
         if(released) return;
         released = true;
         Release();
     }

     // make the native methods static if you can.
     private static native String Read();
     private static native void Release();
}

答案 2 :(得分:2)

同步方法只是语法糖!

这两个是等价的:

 public synchronized String read(){
      return released ? null : Read(); 
 }

 public String read(){
      synchronized(this) {
           return released ? null : Read(); 
      }
 }

因此不会有性能提升。

“手动”(synchronized())同步是有道理的,如果其中一个为真:

  • 有不同的关键部分可能依赖于不同的锁

  • 临界区可能比方法

  • 更短