Equivalent code for instance method synchronization in Java - java

While discussing a Java synchronization question, someone made a comment that the following snippets are not equivalent (and may compile to different bytecodes):
public synchronized void someMethod() {
//stuff
}
and
public void someMethod() {
synchronized (this) {
//stuff
}
}
Are they equivalent?

They are equivalent in function, though the compilers I tested (Java 1.6.0_07 and Eclipse 3.4) generate different bytecode. The first generates:
// access flags 33
public synchronized someMethod()V
RETURN
The second generates:
// access flags 1
public someMethod()V
ALOAD 0
DUP
MONITORENTER
MONITOREXIT
RETURN
(Thanks to ASM for the bytecode printing).
So the difference between them persists to the bytecode level, and it's up to the JVM to make their behavior the same. However, they do have the same functional effect - see the example in the Java Language Specification.
It should be noted, that if the method is overridden in a subclass, that it is not necessarily synchronized - so there is no difference in that respect either.
I also ran a test to block a thread trying access the monitor in each case to compare what their stack traces would look like in a thread dump, and they both contained the method in question, so there is no difference there either.

I made the original comment that the statements are identical.
In both cases, the first thing that happens is that the calling thread will try to acquire the current object's (meaning, this') monitor.
I don't know about different bytecode, I'll be happy to hear the difference. But in practice, they are 100% identical.
EDIT: i'm going to clarify this as some people here got it wrong. Consider:
public class A {
public synchronized void doStuff()
{
// do stuff
}
}
public class B extends A {
public void doStuff()
{
// do stuff
// THIS IS OVERRIDE!
}
}
In this case doStuff() in class B still overrides doStuff() in class A even though it is not synchronized.
Synchronized keyword is never part of the contract! Not for subclasses, not for interfaces, not for abstract classes.

I made the original comment. My comment was that they are logically equivalent, but compile to different bytecode.
I didn't add anything else to justify it at the time because there's not much to justify really-- they just do compile to different bytecode. If you declare a method as synchronized, then that synchronization is part of the method's definition. A synchronized block within a method isn't part of the method's definition, but instead involves separate bytecodes to acquire and release the monitor, as one of the posters above has illustrated. Strictly speaking, they're slightly different things, though to the overall logic of your program, they're equivalent.
When does this matter? Well, on most modern desktop VMs, hardly ever. But for example:
a VM could in principle make optimisations in one case but not the other
there are some JIT compiler optimisations where the number of bytecodes in the method is taken as a criterion for what optimisations to make
a VM without a JIT compiler (admittedly few nowadays, but maybe on an older mobile device?) will have more bytecodes to process on each call

Yes. Using the synchronized keyword on an instance method uses 'this' as a monitor ,also using it on a class method (static method) uses the class' Class object (Foo.class).
This way you can synchronize entire methods, and in the same time, synchronize it with a code snippet in another method using the synchronized-block style.

I can't see any functional difference - both synchronize their entire method bodies on (this). How did the person who commented that these are different justify their statement?

They are not quite equivalent in function. Other code could use reflection to see if your method has the synchronized modifier, but there is no way to tell if a method contains a synchronized block without reading its bytecode.
The ability to determine if a method is synchronized occasionally comes in handy. Personally, I've used that flag to avoid redundant locking when doing synchronization in aspect-oriented programming.

MyObject myObjectA;
MyObject myObjectB;
public void someMethod() {
synchronized (this) {
//stuff
}
}
public void someMethodA() {
synchronized (myObjectA) {
//stuff
}
}
public void someMethodB() {
synchronized (myObjectB) {
//stuff
}
}
In this case:
someMethod blocks entire class
someMethodA blocks myObjectA only
someMethodB blocks myObjectB only
someMethodA and someMethodB can be invoked at the same time

Related

Java Thread Safety: How to handle an instance variable when you have to call methods on it

So I'm pretty good overall when it comes to the thread-safety of code, but I'm currently encountering a situation where I'm not clear on the best way to handle it.
I have an instance variable, non-final because the enclosing class can change its value. This variable is an object that has several methods that get called on it during the application. Here is a quick sample to show what I mean.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething(); //How do I make this line thread-safe?
}
}
Changing the reference of the fooFoo field is easy, just simple synchronization. But what about when the doSomething() method is called on fooFoo? I'm always hesitant to synchronize on an alien method due to deadlock risk.
In the real cases this is based on, there are many different variations of this. My company's application is a sprawling code base that frequently resembles a bowl of spaghetti, so when it comes to writing any kind of synchronized code I'm extra paranoid, because of the tight coupling and the fact that there are developers not only here in the US, but in an offshore firm in eastern europe working on it and I do not trust all of them to make good coding decisions.
So I'm just looking for the best practice to handle this kind of situation in a multi-threaded environment. Thanks.
fooFoo.doSomething(); //How do I make this line thread-safe?
Hint: You can't make that one line thread-safe unless that is the only line in the whole program that ever accesses the object.
Thread-safety is not about making particular lines of code or particular methods thread safe: It's about making data thread safe.
Does fooFoo refer to a mutable object? If not, then that line already is thread safe. But if the object is mutable, then thread-safety, at a minimum, means insuring that unintended interactions between two or more threads can not put that object into an invalid state; and at the worst case it means insuring the consistency of relationships between the fooFoo object and other objects in your program.
Any time there is an important relationship between two or more pieces of data that are shared between threads, then you probably need to throw a synchronized block around any bit of code that could temporarily violate that relationship, and you need to throw a synchronized block around any bit of code that depends on that relationship---even if the code only looks at the data.
In your case you would have to make doSomething() synchronized too, because you need to lock every time a concurrent access on a mutable part of the class occurs. While you are only reading fooFoo in doSomething, you could at the same time be writing fooFoo in setFooFoo(), thus creating a data race. synchronized essentially causes the function call to take a lock that is associated with the Java-object at entry and to release it once you leave the function.
Alternatively you can use a Lock member inside Foo that you take when you do either. This applies in situations, where you may have multiple independent members that may be accessed safely while the other is being altered. In this case taking two different locks may make your code substantially faster.
For completeness sake it should be mentioned that in some older Java versions (Java 5 only I believe) taking the intrinsic lock of the object through a synchronized method, was substantially slower than using a lock object.
For the deadlock problem: you are right to worry about this, but consider it as a separate issue, after you make your object thread-safe in the first place. The question there is what other locks are taken and it is not possible to answer this with just what you posted. Given your object, synchronizing the read/write on the object can not deadlock by itself, because only one operation can be active at the time, and they do not take any other locks from what you show in your code.
It depends upon what your concerns are for thread safety.
If foo is only delegated to you can simply make it volatile. This will prevent threads from cashing a reference to the old value if the reference is updated. FooFoo can then handle it's own thread safety concerns.
private class Foo{
private volatile FooFoo fooFoo;
public void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething();
}
}
If your concern is about thread safety of Foo itself, and it is doing more then just delegating calls you should synchronize relevant methods.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public synchronized void doSomething(){
fooFoo.doSomething();
}
public synchronized void doSomethingElse() {
int values = fooFoo.getValue();
// do some things
fooFoo.setValue(values + somethingElse);
}
}

can I use SchedulingRule to replace synchronzation

Can I change my code from:
class Sample{
private Object _lock=new Object();
public void someMethod(){
synchronized(_lock){
doSomething();
}
}
}
to:
class Sample{
private ISchedulingRule _lock=new SomeSchedulingRule();
public void someMethod(){
try{
Job.getManager().beginRule(_lock);
doSomething();
}finally{
Job.getManager().endRule(_lock);
}
}
}
I'm reading "java concurrency in practice", and they say if I wanna use some explicit lock, I have to guarantee the memory visibility.
So the question is:
If I can guarantee the memory visibility, can I use the code at bottom to replace the code at top(replace intrinsic synchronization with eclipse IJobManager.beginRule and IJobManager.endRule)
Assuming the source code I found here is up to date, you can check that the beginRule method calls implicitJob.begin which has a large synchronized(this) block inside.
If your only goal is to achieve synchronization then the answer is yes.
That said, there are some (hidden) gotchas that you need to be aware of. Since JobManager is designed to prevent dead-locks to some extent, then there are somewhat strict rules for using and defining nested rules (a limitation that Java synchronized blocks don't have). There is no public API for checking whether a thread is holding a rule/lock or not. Also, beginRule cannot be canceled by calling interrupt on waiting thread. To name a few.
I just found a web tutorial on concurrency which makes the following statement:
Well, it turns out that a contract of the Lock interface is that it provides the same >memory barrier behaviour as synchronized.
That's referring to the "Lock" interface in java.util.concurrent. I don't know whether it applies to the ISchedulingRule interface which you show here.

access java synchronized method from native code

I have a java class that has some (private static) synchronized methods which I want to call from native code as well. with some example code it becomes more clear what I mean
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
}
and the associated native code (C++)
void someFunction(JNIEnv * env) {
jclass someClass = env->findClass("SomeClass");
jmethodID methodId = env->GetStaticMethodID(jclass, "method", "()V");
env->MonitorEnter(jclass); // <--- IS THIS NEEDED/ALLOWED
env->CallStaticVoidMethod(jclass, methodId);
env->MonitorExit(jclass); // <--- IS THIS NEEDED/ALLOWED
}
So what I am wondering is if I need to call MonitorEnter/MonitorExit, or if the method synchronization is enforced already by the synchronized attribute on SomeClass.method().
I am not so much interested in rewriting the code. I can think of a few solutions to work around this, but I am interested in what the behaviour is, given a synchronized method that is called from native code.
Section 8.4.3.6 synchronized Methods of the Java Language Specification says that declaring the method synchronized has the same effect as adding a synchronized block within the method.
No, explicit MonitorEnter / MonitorExit are not needed. According to The JNI guide,
...it is preferable to express synchronization constructs in the Java programming language. If, for example, a static native method needs to enter the monitor associated with its defining class, you should define a static synchronized native method as opposed to performing JNI-level monitor synchronization in native code.
Even though your case of calling a Java method from the native code (and not vice versa) isn't directly discussed in the spec, the opposite is not stated either, so I would assume that it works similarly.
If you own SomeClass you can just do
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
private static void synchronizedMethod() {
method();
}
}
and just call synchronizedMethod() from C++.

Question on jvm-wide properties and multithreading

I need to use (at the moment) some java apis that -unfortunatelly- can be "configured" only via jvm properties.
I understand that this can affect multithreading, since it can be the case that one thread modifying the properties can affect the others running.
So I thought to do this inside a synchronized method e.g.
public static sychronized void someMethod(){
Security.setProperty("responderURL",IP);
//do code here
}
It seems it is ok, but I was wondering if there any pitfalls on this and whether there is any kind of design pattern for cases like these?
Thanks
When you create a synchronized static method, it synchronizes on the class that the method is in. This means that only one method in that class will be able to run at a time. If that solves your problem, then perfect.
However, if any other method in the JVM modifies those properties outside of that class or outside of a method that's synchronized on the class, then your efforts won't have any effect.
You dont need to synchronize , System.setProperty is already synchronized method, and although System.getProperty is not synchronized, Properties class extends HashTable which has syncronized method to access its key-value pairs.As a result, you dont need to do worry about synchronizing issues..
EDIT :
Some clarifications about my answer ;
1.If your method should work as an atomic unit, it should be synchronized , such as ;
public static sychronized void someMethod(){
if (System.getProperty("responderURL")==null)
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(System.getProperty("responderURL"),8080,"test.txt");
}
You should synchronized your method, because while Thread 1 is checking responderURL property , Thread 2 could set this property.
2.But if your method sets only responderURL property, and its functionality does not depend respondrURL property current value, you dont need to synchronize your method..
public static void someMethod(){
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(IP,8080,"test.txt");
}
Using synchronized won't help you here. The only thing synchronized does in your example is ensure that two threads cannot call your synchronized method simultaneously.
public class Foo {
public static synchronized void bar() {
//...
}
}
is exactly the same as
public class Foo {
public static void bar() {
synchronized (Foo.class) {
//...
}
}
}
i.e. only code that can see Foo.class and synchronizes on it will be affected by your synchronization. Since code in whatever libraries you are calling obviously does not know about Foo.class, synchronizing on it will not have any effect.
If you want to guarantee that these system properties are set before any code runs which might read the values can possibly run, the most bulletproof way is to pass them as -D arguments to the java command which starts the JVM, e.g.
java -DresponderURL=http://foo.bar.
The next best approach is, as you are doing, set the properties in some method called early in VM startup. It is always preferable to do it with command-line arguments if possible, though, for this reason: If any such properties are read in static{} blocks in the libraries you're using, those blocks may run before your code does, because Java's bytecode verifier may cause those classes to be initialized before your code does anything that calls them (you can avoid this by passing -Xverify:none to the Java command, but if you can do that, you might as well just set the system properties there anyway).
If this is one time configuration, you do this inside a static initialization block. If not, what you have is the classic reader-writer problem. The java.util.concurrent javadocs have some good sample solutions.

Can a shared resource safely be used as the lock for a synchrnized block?

I often find myself with code like
private static final MyType sharedResource = MyType();
private static final Object lock = new Object();
...
synchronized(lock)
{
//do stuff with sharedResource
}
Is this really neccessary or could sharedResource be used as the lock itself like
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource)
{
//do stuff with sharedResource
}
Note: synchronized blocks shown in the examples would live within methods doing work and are not methods themselves or synchronized methods.
EDIT: A very good point has been pointed out in some of the answers that if we are dealing with multiple shared resources that the first "Object" technique is far safer.
WARNING The fact that sharedResource is static is important! If it is static then synchronized methods or synchronized blocks locking on this won't work. The lock object must also be static.
Pros and cons of both
First option pros: Allows locking on concept, not on Objects. If you had to lock on multiple resources for a single action (which is usually not advised, but sometimes necessary) you could do this with much less worry about race conditions.
cons: The object could still be modified, so you need to ensure access to the object is restricted to methods that abide by the external lock.
Second option pros: Lock on the object should prevent others from modifying it (although you should double check the exact symantics.) EDIT: Has the same con as above - if the methods aren't synchronized internally, you could still run into methods that don't abide by the contract.
cons: You block access to all methods, even those unrelated to what you're trying to operate, which could cause slowdowns and possibly deadlock. You could easily make the case, however, that if that's the case your Object is doing too much work and should be broken up.
EDIT: Allow me to clarify part 2 here (the case to break up MyType into MyFoo and MyBar is open for debate...)
class MyType {
Foo foo;
Bar bar;
void doFoo() { foo.do(); }
void doBar() { bar.do(); }
}
class MyActions {
MyType thing;
void lotsOfFoo() {
// blocks bar :-(
synchronized(thing) { thing.doFoo(); }
}
void lotsOfBar() {
// blocks foo :-(
synchronized(thing) { thing.doBar(); }
}
}
Personally, I use option 1 much more often (that's why I'm unsure about that part in option 2).
The only problem I see, with using sharedResource as a lock if MyType has methods defined as synchronized itself. In this case, some strange behaviour my occur that was not intended by the developers of MyType. (See glowcoder's comment for an example.)
Otherwise it should be fine, however if you do only need one lock anyway, then just synchronize on this instead of introducing an additional dummy object.
Btw, did you itentionally make your lock object static? Because this means that all instance lock on the same monitor, i.e. they can block each other, which may not bee the behaviour you intended.
Yes, you can absolutely do that.
In fact it improves clarity and reduces clutter.
If I remembered right, synchronized is a monitor, it grants that only one thread can access that object at any given time in the same JVM. So I think you are only accessing shardResouce, synchronizing on the shardResouce is sufficient.
Personally, I don't usually synchronize on an arbitrary lock. That is, I'd usually do something along the lines of your second approach:
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource) {
//do stuff with sharedResource
}
Of course, before running synchronized code, the lock for the target object must be obtained. Often, I take the locking "down" a step further, so to speak. Meaning, I would synchronize on a method within "sharedResource." As in:
public class MyType {
public void synchronized doWork() {
}
}
But when it comes to this kind of thing, it's hard to make generalizations because there are exceptions to every rule. In the end, your overall architecture requirements will dictate where your locking should occur. For me, most often, I find myself synchronizing the top-level method that accesses the shared resources and it is thereby more rare to lock on an object who does nothing more than serve as a lock.
EDIT: minor grammar fixes

Categories