Reputation: 28706
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
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
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
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