ben75
ben75

Reputation: 28706

performance of synchronized method vs block

I've a class where all methods need to be synchronized (no static method). One of those method will be called once every 50 ms.

I'm wondering where putting the synchronized keyword to have the shortest execution time ?

i.e. Is there any differences between the 2 options detailed bellow regarding execution time ?

Option 1 (synchronized methods)

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

Option 2 (synchronized block)

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

Upvotes: 2

Views: 4292

Answers (3)

Dariusz
Dariusz

Reputation: 22241

Synchronized methods are just syntactic sugar!

These two are equivalent:

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

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

Hence there will be no performance improvement.

"Manual" (synchronized()) synchronization makes sense if either is true:

  • there are different critical sections which may depend on a different lock

  • critical section may be shorter than the method

Upvotes: 3

Joachim Sauer
Joachim Sauer

Reputation: 308001

Option #1 works, and is almost perfect, except that the synchronized-on object is visible to the outside, which should be avoided if possible.

Option #2 is very dangerous and probably wrong, as the object you synchronize on changes (when released changes from Boolean.TRUE to Boolean.FALSE it will synchronize on another object!

Option #3 would be this:

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

The idea is to use an object as the monitor that's not accessible from outside your code (see this page to read about my using a new Object[0] in place of the more common new Object()). This way, no other synchronization can interfere with your synchronization.

Upvotes: 6

Peter Lawrey
Peter Lawrey

Reputation: 533442

You can't have a synchronized class.

As Joachim points out, Option 2 is wrong as you are locking on a) a field which changes and b) a global object.

The synchronized methods is not only the only one which works but the simplest of those which would so I would use that.

A typical lock takes around 50 nano-seconds, so if you call these methods every 50,000,000 nano-seconds, it is highly unlikely that it will make any difference.

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

Upvotes: 6

Related Questions