This is a successor of my previous question, Is this variable being safely accessed by using synchronization?
For the following program,
Class SubClassB extends SuperClassA {
protected int c;
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized ( (SuperClassA) this) {
c--;
}
}
}
Would the counter "c" be accessed thread safe ? I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ? If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
This strange simulated code comes from the following real life example where SuperClassA is a base class that is not supposed to be modified,
Class SuperClassA {
protected int c;
public void dec() {
synchronized (this) {
c--;
}
}
}
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
super.dec();
}
}
In this example, the "dec()" method in SubClassB calls its superclass's "dec()" method which performs a lock to a "this" object that I suppose to be "SuperClassA.this". If the locked object in SubClassB's "inc()" method is not exactly the same as the locked object in SubClassB's "dec()" method, then I am wondering the inherited counter "c" in SubClassB may NOT be safely accessed by different threads. I feel that there is some ambiguities in using the "this" reference in synchronized blocks.
In the real life example, if I want SubClassB's counter "c" to be thread safe, do I need to add one more synchronized block in its "dec()" method, like this,
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized (this) {
super.dec();
}
}
}
But it seems that such added block is not elegant and may be redundant !
Does anyone have some ideas on these questions. Thanks in advance.
Lawrence
The code is thread-safe, because (SomeObject) this adn this are the same object. A cast doesn't transform an object into another object.
The code lacks encapsulation, though, because it lets any subclass access the protected c field in an unsynchronized way. So, any subclass might use c++ or c-- without any synchronization. The field should be private.
Would the counter "c" be accessed thread safe ?
Yes, it's using the same lock object.
I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ?
Yes.
If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
Yes. Even if you cast the instance to something it can be casted to (even Object), it'll still refer to the same object.
[...] But it seems that such added block is not elegant and may be redundant !
It is redundant. Extra synchronization is required only if you call multiple synchronized methods and the combined effect must be atomic.
it seems to me that "(SuperClassA) this" is not equal to "this"
Wrong; synchronization is done on objects, and casting only changes the compile-time type, is has no effect on object identity.
Thus, you don't have to add an extra synchronization in the subclass.
All three examples are correct as far as synchronization is concerned.
There's only one monitor associated with any object.
Casting this to a base class inside synchronized makes no difference.
For the same object, it doesn't matter whether synchronized(this) is invoked in the context of the derived class or the base class: the same lock is used in both cases.
Related
I have a question in singleton pattern.
In singleton pattern we write
synchronized(ClassName.class){
// other code goes here
}
What is the purpose of writing ClassName.class?
In a member method (non-static) you have two choices of which monitor (lock) to use: "this" and "my class's single static lock".
If your purpose is to coordinate a lock on the object instance, use "this":
...
synchronized (this) {
// do critical code
}
or
public synchronized void doSomething() {
...
}
However, if you are trying to have safe operations including either:
static methods
static members of your class
Then it is critical to grab a class-wide-lock. There are 2 ways to synchronize on the static lock:
...
synchornized(ClassName.class) {
// do class wide critical code
}
or
public static synchronized void doSomeStaticThing() {
...
}
VERY IMPORTANTLY, the following 2 methods DO NOT coordinate on the same lock:
public synchronized void doMemberSomething() {
...
}
and
public static synchronized void doStaticSomething() {
...
}
Each class (for example Foo) has a corresponding, unique instance of java.lang.Class<Foo>. Foo.class is a literal of type Class<Foo> that allows getting a reference to this unique instance. And using
synchronized(Foo.class)
allows synchronizing on this object.
The object that you pass into the synchronized block is known as a monitor. Since the object that represents the class className.class is guaranteed to only exist once in the JVM it means that only one thread can enter that synchronized block.
It is used within the singleton pattern to ensure that a single instance exists in the JVM.
According to the Java Language Specification, constructors cannot be marked synchronized because other threads cannot see the object being created until the thread creating it has finished it. This seems a bit odd, because I can indeed have another thread view the object while it's being constructed:
public class Test {
public Test() {
final Test me = this;
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
I know that this is a pretty contrived example, but it seems in theory that someone could come up with a more realistic case where marking the constructor synchronized would be legitimate in order to prevent races with threads like this one.
My question is this: is there a reason that Java would specifically disallow the synchronized modifier on a constructor? Perhaps my above example is flawed, or perhaps there really is no reason and it's an arbitrary design decision. In either case, I'm really curious and would love to know the answer.
If you really need synchronization of the rest of the constructor versus any threads which anyhow gets a reference to your not-yet-totally-constructed object, you can use a synchronized-block:
public class Test {
public Test() {
final Test me = this;
synchronized(this) {
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
synchronized(me) {
// do something dangerous with 'me'.
}
}
}.start();
// do something dangerous with this
}
}
}
Usually it is considered bad style to "give out" your not-yet-constructed object like this, so a synchronized constructor is not necessary.
In some corner cases a synchronized constructor would be useful. Here is a more realistic example, from the discussion of Bozho's answer:
public abstract class SuperClass {
public SuperClass() {
new Thread("evil") { public void run() {
doSomethingDangerous();
}}).start();
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) { /* ignore */ }
}
public abstract void doSomethingDangerous();
}
public class SubClass extends SuperClass {
int number;
public SubClass () {
super();
number = 2;
}
public synchronized void doSomethingDangerous() {
if(number == 2) {
System.out.println("everything OK");
}
else {
System.out.println("we have a problem.");
}
}
}
We want that the doSomethingDangerous() method is only called after construction of our SubClass object is complete, e.g. we only want the "everything OK" output. But in this case, when you only can edit your SubClass, you have no chance of achieving this. If the constructor could be synchronized, it would solve the problem.
So, what we learn about this: never do something like I did here in the superclass constructor, if your class is not final - and don't call any non-final methods of your own class from your constructor.
The question has been raised on a discussion list used by the writers of the Java concurrent API and the Java Memory Model. Several answers were given, in particular Hans Boehm replied:
Some of us (myself included IIRC) actually argued during the Java memory model deliberations that synchronized constructors should be allowed. Now I could go either way on it. Client code shouldn't use races to communicate the reference, so it shouldn't matter. But if you don't trust the clients of [your class], I think synchronized constructors could possibly be useful. And that was much of the reasoning behind final field semantics. [...] As David said, you can use synchronized blocks.
Because synchronized guarantees that actions on the same objects are not to be performed by multiple threads. And when the constructor is called you still don't have the object. It is logically impossible for two threads to access the constructor of the same object.
In your example, even if a method is invoked by the new thread, it is no longer about the constructor - it is about the target method being synchronized or not.
Constructor Modifiers section in JLS clearly says
There is no practical need for a constructor to be synchronized, because it would
lock the object under construction, which is normally not made available to other
threads until all constructors for the object have completed their work.
So there is no need for constructor to be synchronized.
Also it is not recommended to give out the objects reference(this) before object is created. One of the possible ambiguous situations would be to give out the objects reference is superclass constructor when subsclass object is being created.
In your example, the constructor is only actually called once from one thread.
Yes, it is possible to get a reference to an incompletely constructed Object (some discussions around double check locking and why it is broken reveal this problem), however, not by calling the constructor a second time.
Syncronized on the constructor would prevent two threads from calling the constructor on the same Object simultaneously, and that is not possible, as it is never possible to call the constructor on an object instance twice, period.
I see little reason to forbid constructors to be synchronized. It would be useful in many scenarios in multi-threaded applications. If I understand the Java Memory Model correctly (I read http://jeremymanson.blogspot.se/2008/11/what-volatile-means-in-java.html) the following simple class could have benefited from a synchronized constructor.
public class A {
private int myInt;
public /*synchronized*/ A() {
myInt = 3;
}
public synchronized void print() {
System.out.println(myInt);
}
}
In theory, I believe a call to print() could print "0". This could happen if an instance of A is created by Thread 1, the reference to the instance is shared with Thread 2, and Thread 2 calls print(). If there is no special synchronization between the write myInt = 3 of Thread 1 and the read of the same field by Thread 2, Thread 2 is not guaranteed to see the write.
A synchronized constructor would fix this issue. Am I right about this?
The following code can achieve the expected result for synchronized constructor.
public class SynchronisedConstructor implements Runnable {
private int myInt;
/*synchronized*/ static {
System.out.println("Within static block");
}
public SynchronisedConstructor(){
super();
synchronized(this){
System.out.println("Within sync block in constructor");
myInt = 3;
}
}
#Override
public void run() {
print();
}
public synchronized void print() {
System.out.println(Thread.currentThread().getName());
System.out.println(myInt);
}
public static void main(String[] args) {
SynchronisedConstructor sc = new SynchronisedConstructor();
Thread t1 = new Thread(sc);
t1.setName("t1");
Thread t2 = new Thread(sc);
t2.setName("t2");
t1.start();
t2.start();
}
}
Such a synchronization might make sense in some very rare cases, but I guess, it's just not worth it:
you can always use a synchronized block instead
it'd support coding in a pretty strange way
on what should it synchronize? A constructor is a sort-of static method, it works on an object but gets called without it. So synchronizing on the class also makes (some) sense!
When in doubt, leave it out.
Note that constructors cannot be synchronized — using the synchronizedkeyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
Does the following mean that only ONE thread can be in ANY method of the object? Or can a multiple threads be in DIFFERENT methods just not the same one? Why?
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Does the following mean that only ONE thread can be in ANY method of the object?
For your specific example, yes, because all the methods are synchronized and non-static.
If your class had any unsynchronized methods, then the unsynchronized methods would not be blocked.
If your class used synchronized blocks instead of methods and synchronized them on different locks, it could get much more complex.
Does the following mean that only ONE thread can be in ANY method of the object?
Yes. Non-static synchronized methods implicitly synchronize on this. It's equivalent to:
public void increment() {
synchronized(this) {
c++;
}
}
If this were a real piece of code (I know it's not), I would recommend throwing out your SynchronizedCounter class entirely and using AtomicInteger instead.
Of course, they are synchronized on the this object. If you had written your own synchronized block with different objects for the different methods you have then it won't be the case.
Let's say we have an object whose methods/fields are synchronized on "this". This question is actually about "this" as I think I have a hard time what "this" reference means.
So our object is:
class A {
private Field a;
private Field b;
public synchronized void doSomething() {
//something with a
}
public synchronized void somethingElse() {
//do something as with b
}
}
Then we have another object or method that takes A objects and do work on a and b via doSomething and somethingElse methods. So I need to keep the state consistent while I process A objects, hence I synchronize. Let's say those A objects are values of a Map. Then I am iterating over the values and do the things that I do. So the question is, is it thread-safe to do it in the following way:
for(A aObject : map.values()) {
synchronized(aObject) {
aObject.doSomething();
aObject.somethingElse();
}
}
If the "this" reference is the same reference as aObject, I think I shouldn't be in trouble. But what if I do it like this:
for(A aObject : map.values()) {
A anotherReference = aObject;
synchronized(anotherReference) {
anotherReference.doSomething();
anotherReference.somethingElse();
}
}
Is it still thread-safe? I mean can I synchronize on a local copy of a lock reference?
Note: this is an oversimplification of something I need to do in my code.
The synchronisation monitor belongs to the object that is referenced, not the reference, so your two for loops are equivalent, they both synchronise on the same object.
Now a synchronized method
public synchronized void foo() {
// do stuff
}
is exactly equivalent to
public void foo() {
synchronized(this) {
// do stuff
}
}
so in the loop
for(A aObject : map.values()) {
synchronized(aObject) {
aObject.doSomething();
aObject.somethingElse();
}
}
the synchronized block is locking the same monitor as the doSomething() and doSomethingElse() methods use themselves. What you gain from the synchronized block is that no other thread can sneak in and call either of those methods on the same A instance in between these two calls.
you seems to be confused about what references are, so i would go read up on them. when you use a synchronized block, you are not synchronizing on the reference itself, but on the object instance to which the reference refers.
for example:
Object a = new Object();
Object b = a;
synchronized(a) { ... }
synchronized(b) { ... }
these two synchronized blocks are synchronizing on the same Object instance because a and b refer to the same Object instance.
Following from that, a synchronized method is the same as synchronizing on the this reference.
for example:
public class A {
public synchronized void doStomething() { ... }
public void doSomethingElse() { synchronized(this) { ... } }
}
both of these methods are synchronizing on the same Object instance (the current instance), using the self reference known as this. you can rewrite either example as the other example and they are equivalent.
So, returning to your original example, i hope you will understand that when you synchronized on an Object instance externally through a reference (as my first example), it is doing the same thing as an Object synchronizing internally on itself.
To wrap, your last example is a common idiom when working on synchronized collections as it enables the caller to ensure that 2 operations are performed atomically with respect to the Collection.
for example:
// this will result in a List where all methods are internally synchronized
List<Object> syncList = Collections.synchronizedList(new ArrayList<Object>());
// i can safely perform an atomic operation on the List using this pattern
synchronized(syncList) {
if(syncList.isEmpty()) { // <- synchronized method call
syncList.add(...); // <- synchronized method call
}
}
In Java we have two basic synchronization idioms: synchronized methods and synchronized statements.
When you use the first idiom (synchronized methods) as in the following code:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
You have two main effects:
1) it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
2) when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
Another way to create synchronized code is with synchronized statements. Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock:
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
In your code you're using both of these idioms. Then, your first for loop doesn't need the synchronized(aObject) because your class methods are already synchronized methods.
source: http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
But let's say your class methods weren't synchronized. Your second code example:
for(A aObject : map.values()) {
A anotherReference = aObject;
synchronized(anotherReference) {
anotherReference.doSomething();
anotherReference.somethingElse();
}
}
Still works, because in Java every object has an intrinsic lock associated with it. When you call synchronized(Object o) you're acquiring the lock associated with the Object: anotherReference, that in your case is the aObject.
Let's think about two Thread: T1 and T2.
If T1 call this for loop before T2, it acquires the intrinsic lock associated with the aObject and T2 won't able to do the same till T1 will end both methods: doSomenthing() and somethinElse().
What is the difference between synchronizing a static method and a non static method in java?Can anybody please explain with an example. Also is there any difference in synchronizing a method and synchronizing a block of code?
I will try and add an example to make this extra clear.
As has been mentioned, synchronized in Java is an implementation of the Monitor concept. When you mark a block of code as synchronized you use an object as a parameter. When an executing thread comes to such a block of code, it has to first wait until there is no other executing thread in a synchronized block on that same object.
Object a = new Object();
Object b = new Object();
...
synchronized(a){
doStuff();
}
...
synchronized(b){
doSomeStuff();
}
...
synchronized(a){
doOtherStuff();
}
In the above example, a thread running doOtherStuff() would block another thread from entering the block of code protecting doStuff(). However, a thread could enter the block around doSomeStuff() without a problem as that is synchronized on Object b, not Object a.
When you use the synchronized modifier on an instance method (a non-static method), it is very similar to having a synchronized block with "this" as the argument. So in the following example, methodA() and methodB() will act the same way:
public synchronized void methodA() {
doStuff();
}
...
public void methodB() {
synchronized(this) {
doStuff();
}
}
Note that if you have a methodC() in that class which is not synchronized and does not have a synchronized block, nothing will stop a thread from entering that method and careless programming could let that thread access non-safe code in the object.
If you have a static method with the synchronized modifier, it is practically the same thing as having a synchronized block with ClassName.class as the argument (if you have an object of that class, ClassName cn = new ClassName();, you can access that object with Class c = cn.getClass();)
class ClassName {
public void static synchronized staticMethodA() {
doStaticStuff();
}
public static void staticMethodB() {
synchronized(ClassName.class) {
doStaticStuff();
}
}
public void nonStaticMethodC() {
synchronized(this.getClass()) {
doStuff();
}
}
public static void unSafeStaticMethodD() {
doStaticStuff();
}
}
So in the above example, staticMethodA() and staticMethodB() act the same way. An executing thread will also be blocked from accessing the code block in nonStaticMethodC() as it is synchronizing on the same object.
However, it is important to know that nothing will stop an executing thread from accessing unSafeStaticMethodD(). Even if we say that a static method "synchronizes on the Class object", it does not mean that it synchronizes all accesses to methods in that class. It simply means that it uses the Class object to synchronize on. Non-safe access is still possible.
In short if you synchronize on a static method you will synchronize on the class (object) and not on an instance (object). That means while execution of a static method the whole class is blocked. So other static synchronized methods are also blocked.
Synchronization in Java is basically an implementation of monitors. When synchronizing a non static method, the monitor belongs to the instance. When synchronizing on a static method, the monitor belongs to the class. Synchronizing a block of code is the same idea, but the monitor belongs to the specified object. If you can get away with it, synchronized blocks are preferable because they minimize the time each thread spends in the critical section
There is virtually no difference between synchronizing a block and synchronizing a method. Basically:
void synchronized m() {...}
is the same as
void m() { synchronized(this) {...} }
By comparison a static synchronized method is the same as:
static void m() { synchronized(MyClass.class) {...} }
Dude, just a hint. Not related to your question:
If any do*Stuff() methods does either
this.a= /*yet another*/ new Object();
or
this.b= /*yet another*/ new Object();
then you are screwed. Because the lock is inside the value, not inside the reference. See Java synchronized references
From javadoc https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.
public static synchronized void getInstance(){}
When we acquire a lock on any class, we actually acquire a lock on "Class" class instance which is only one for all instances of class.
public synchronized void getInstance(){}
we can create multiple object's of a class and each object will have one lock associated with it.