What does this java code mean? Will it gain lock on all objects of MyClass?
synchronized(MyClass.class) {
//is all objects of MyClass are thread-safe now ??
}
And how the above code differs from this one:
synchronized(this) {
//is all objects of MyClass are thread-safe now ??
}
The snippet synchronized(X.class) uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.
With synchronized(this) the block is guarded by the instance. For every instance only one thread may enter the block.
synchronized(X.class) is used to make sure that there is exactly one Thread in the block. synchronized(this) ensures that there is exactly one thread per instance. If this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instance synchronized(this) is enough.
To add to the other answers:
static void myMethod() {
synchronized(MyClass.class) {
//code
}
}
is equivalent to
static synchronized void myMethod() {
//code
}
and
void myMethod() {
synchronized(this) {
//code
}
}
is equivalent to
synchronized void myMethod() {
//code
}
No, the first will get a lock on the class definition of MyClass, not all instances of it. However, if used in an instance, this will effectively block all other instances, since they share a single class definition.
The second will get a lock on the current instance only.
As to whether this makes your objects thread safe, that is a far more complex question - we'd need to see your code!
Yes it will (on any synchronized block/function).
I was wondering about this question for couple days for myself (actually in kotlin). I finally found good explanation and want to share it:
Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.
Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.
Plus to notice why .class. It is just because .class is equivalent to any static variable of class similar to:
private final static Object lock = new Object();
where lock variable name is class and type is Class<T>
Read more:
https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/
Related
I am trying to synchronize read write operations on xml file from multiple methods in multiple classes. To achieve this, I am synchronizing this operations by using class level lock.
Code sample:
Test1.java:
public class Test1 {
public void method1() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
Test2.java
public class Test2 {
public void method2() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
To achieve this class level lock, consider following sample code:
synchronized(CommonUtility.class) {
.
.
.
}
What are the impacts of using Object.class instead of CommonUtility.class, like:
synchronized(Object.class) {
.
.
.
}
I think both approaches aren't ideal.
First of all, this here suggests:
You might wonder what happens 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.
In other words: when you use synchronized(CommonUtility.class) you implicitly get "synchronized" with all static synchronized methods within CommonUtility. And worse: imagine that class has no such methods today. But next week, someone adds such a static synchronized method in that utility class, assuming that only calls to that method go through that monitor. Worst case, that could lead to some ugly (runtime only) surprises.
Then: going for even broader scope (by using Object.class) makes things worse.
My answer: avoid using class objects in the first place.
IMO, the idea of "class level" lock and "object level" lock is distracting. There is only one underlying synchronization mechanism in Java: synchronized (o) { ... } where o can be any Java object (Note that in Java MyClass.class is an object.)
When you write,
synchronized SomeType foobar(...) { ... }
That's really just a shortcut way of using an instance as the lock object that protects its own member variables.
SomeType foobar(...) {
synchronized (this) {
...
}
}
Same goes for so-called "class level" locking: It's just a shorthand way of using the class itself as the lock object that protects its own static members.
Speaking of which...
Good practice keeps the lock object near the data that it protects (for some definition of "near"). If the data are private, then the lock object ought to be private. If the data are members of some instance, then the lock object ought to be members of the same instance, etc.
Object.class isn't particularly "near" anything. It will work as well as any other object, but using it makes your code harder to understand, because the reader will spend time wondering what motivated you to choose Object.class, and wondering whether your choice was based on a misunderstanding.
My own preference, for protecting instance members, looks like this:
class MyClass {
private final Object lock = new Object();
private SomeType someVariableThatNeedsProtection = ...;
private SomeOtherType someOtherVariableThatAlsoNeedsProtection...;
...
public ... foobar(...) {
synchronized(lock) {
...
}
}
}
And, If I need to protect static members:
...
private static final Object lock = new Object();
...
The lock variable is private, just like the data it protects. Nobody who wants to understand your code will need to spend any time searching for anything else that is protected by the same lock object because they know it can't be accessed from outside of the MyClass methods.
The lock variable also is final. That will save readers from having to examine your code to make sure that it's always the same object that gets used as the lock. (Hint: if you think you need to be able to assign the lock variable, then you are either doing something that's sophisticated beyond the comfort level of many programmers, or you are making a bad mistake.)
I am trying to synchronize read write operations on XML file from multiple methods in multiple classes. To achieve this, I am synchronizing this operation by using class level lock.
That is not a good idea. You should have a single class (maybe XmlHelper) which manages the XML file and does the locking. XmlHelper would be used in the multiple methods in multiple classes and would control the locking on the file instead of multiple classes having to worry about it. That's much better object design.
Maybe something like:
public class XmlHelper {
public XmlHelper(File xmlFile) {
public synchronized SomeObject readSomething() { ... }
public synchronized void writeSomething(SomeObject someObject) { ... }
}
Then your Test1 and Test2 classes must share the same instance of the XmlHelper class so their locks will block each other. Instance level locks aren't always a great idea again because locks should be as fine-grained as possible, but it is fine in your application since the XmlHelper is designed for multiple classes to lock their IO operations.
What are the impacts of using Object.class instead of CommonUtility.class, like:
As others have mentioned, locking on the class is the same as calling a synchronized static method. This pattern should be used very sparingly since the lock is so coarse grained. What if your program needed to read/write to 2 XML files at the same time? Your class level lock would cause IO operations to the 2 files block each other -- not optimal.
If you locked on Object.class then any other class which happens to be doing the same lock will block your threads unnecessarily. God help you.
A race condition is getting hit. For example: thread1 reads file contents and updates read contents. Before thread1 writes back to file, thread2 reads content. Then thread1 writes updated contents to file. And at last thread2 writes content to file. This is leading to contents loss,
There are a couple of ways of doing this. You could have some sort of update method on your XmlHelper class:
public synchronized void updateObject(...) {
SomeObjecto obj = readSomething();
// adjust object here based on the arguments
writeSomething(obj);
}
If each of the threads need to do their own updating then they will need to lock externally on the same object. I recommend locking on the shared instance of the XmlHelper.
synchronized (xmlHelper) {
...
}
The locking on the class object will work but it is far to big a hammer to be recommended. Again, if you have 2 instances of the XmlHelper working on 2 different files, you would not want IO operations on 2 different files to block each other.
Assuming I have two different objects of same class, do they will able to execute the same synchronized method at the same time because the lock is on the object ant not on the method.
Example:
MyCLass cc= new MyCLass();
MyCLass cc1= new MyCLass();
Now create two thread
t1 --- it will call cc.meth
t2--it will call cc1.meth
// in this case t1 thread get lock on object cc and t2 thread get lock on object cc1.. it will work
synchronized meth(){
}
is it correct?
I think your question is answered here https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html, that tell that just one instance of the same class is locked while executing a synchronized method, obviously even if executed by a thread.
You are right. Synchronized methods lock their instance, not the class nor the method (for synchronized static methods, see below...).
So, on a given instance, only one thread can be inside any of its synchronized methods, but that does not block threads working with other instances of the same class.
Synchronized static methods lock the class (they don't have a this instance), so of all threads only one at a time can be executing inside a synchronized static method of the given class.
And if you need some other locking scheme, you can use a synchronized(someObject) { ... } block, which synchronizes on someObject, and then you are free to select the object that represents the mutual-exclusion group.
So, a synchronized method A.b() is equivalent to synchronized(this) {...} or (in the static case) synchronized(A.class) {...}.
synchronized implemented by monitorenter. You can see it in your byte code. monitorenter use the object monitor - the monitor of the instance of the class (not the class itself). So it is the expected behavior. If two threads try to execute synchronized methods of two different instances at the same time, both should not be blocked.
Actually it is better to avoid synchronized if the objects are not shared because synchronized is not good for performance. You should start thinking about synchronized only when you know that the object will be shared by more than one thread, which is not your case.
EDIT:
More simple explanation is that this code:
public synchronized void meth() {
...
}
equivalent to:
public void meth() {
synchronized (this){
...
}
}
I have seen this NullPointerException on synchronized statement.
code:
synchronized(a){
a = new A()
}
So according to the above answer I have understood that it is not possible to use synchronized keyword on null reference.
So I changed my code to this:
synchronized(a = new A()){}
But am not sure if this is identical with my original code?
update:
what I want to achieve is lock the creation of a ( a = new A() )
Synchronized requires an object that will provide locking mechanism. It can be any object (in fact, synchronized without parameters will synchronize on this), but Java API provides classes dedicated to this functionality, for example ReentrantLock.
In code you provided every call to function containing synchronized block will use different object for locking, effectivly making synchronization useless.
Edit:
Since you updated your post with what you are actually trying to accomplish I can help you more.
public class Creator {
private A a;
public void createA() {
synchronized(this) {
a = new A();
}
}
}
I don't know if this fits your design since the code sample you provided is very small, but you should get the idea. Here instance of the Creator class is used to synchronize the creation of A. If you share it across multiple threads, each one of them calling createA(), you can be sure that one instantiation process will be finished before another one begins.
synchronized(a = new A()){}
so what it will do is it will create a new object of class A and use
that as Lock, so in simple word every thread can enter in synchronized
block anytime because each thread will have new lock and there will be
no other thread that is using that object as lock so every thread can
enter your synchronized block anytime and outcome will be no
synchronization
For Example
class TestClass {
SomeClass someVariable;
public void myMethod () {
synchronized (someVariable) {
...
}
}
public void myOtherMethod() {
synchronized (someVariable) {
...
}
}
}
here we can say Then those two blocks will be protected by execution
of 2 different threads at any time while someVariable is not modified.
Basically, it's said that those two blocks are synchronized against
the variable someVariable.
But in your case there will be always a new object so there will be no synchronization
These two code snippets are not equivalent!
In the first code snippet you synchronize on some object referenced by a, and afterwards you change the reference which will not change the synchronization object.
In the second snippet you first assign a newly created object to reference a and then synchronize on it. So the synchronization object will be the new one.
Generally, it is a very bad idea to change the reference which is used in the synchronized statement, regardless whether it is done inside the block (first code) or diretcly in the synchronized statement (second code). Make it final! Oh, and it mustn't be null, either.
I am aware of locking concepts with synchronization of static and non static methods to lock classes and instances respectively. What I am not able to understand is, how is class level lock achieved? I mean, class is a template only, with no physical significance. So, when we say that class level locking is achieved with synchronizing static methods what happens then? Do all the objects of that class get locked or some other process?
With what I could find out with my search is that there are class objects (Class.class) and lock is acquired on this class object. But then how are all instances of that class also locked?
Do all the objects of that class get locked or some other process?
First, let's talk about what what it means to "lock" an object.
Foobar foobar = new Foobar();
synchronized (foobar) {
...
}
You might say that the foobar object is "locked" when a thread is in the synchronized block. But what does that do for the program? A lot of newbies make the mistake of thinking that it will prevent other threads from accessing the object. But, that is not true. What synchronized does--the only thing synchronized does--is to guarantee that no more than one thread can be synchronized on the same object at the same time.
The programmer's intent in the example above might be to prevent other threads from seeing foobar in an inconsistent state. In that case, every method and every fragment of code that accesses foobar must be synchronized on foobar. Imagine foobar as big room with many doors. Each method that uses foobar is like a different door. If you want to keep people out of the room, it doesn't help to lock just one door. You have to lock all of them.
So now, to your question:
when we say that class level locking is achieved with synchronizing static methods what happens then?
Simple. This:
class Foobar {
static synchonized void do_something() {
...
}
}
Does exactly the same as this:
class Foobar {
static void do_something() {
synchronized(Foobar.class) {
...
}
}
}
You always synchronize on an Object. Well, a class is an Object. When a static method is synchronized, that just means that the method body is synchronized on the class object.
Since a class is a singleton object, that means that no two threads can get into the same static synchronized method at the same time. In my earlier example, the variable foobar could refer to different objects at different times, but in the static example, Foobar.class is guaranteed always to refer to the same singleton.
Edit: As, #Danny pointed out, there is no connection between a block that is synchronized on the Foobar class, (my second example) and a block that is synchronized on an instance of the Foobar class (my first example). The instance and the class object are two different objects, so nothing prevents one thread from synchronizing on the instance while another thread is synchronized on the class. Likewise, nothing prevents two different threads from synchronizing on two different instances. Another mistake that newbies often make is to think that only one thread at a time can enter this synchronized block:
Integer n = ...;
synchronized (n) {
n = n+1;
...
}
But it's not true. It's not the variable, n, that is locked, it's a particular instance of the Integer class. Each thread that enters the block creates a new Integer instance and assigns it to n. So when the next thread comes along, n no longer refers to the same instance that the first thread has synchronized.
I was wondering if there is a situation where this statement will be true and needed. All the examples I have seen only synchronize on the "this" reference. Can someone tell me how a block of code in one object can be synchronized on any other reference apart from this ?
Yes the statement is true.
There are several reasons why one would want NOT to use an intrinsic monitor (synchronized(this)) - one of these reasons is that it can create liveness issues - in the code below, B uses an instance of A as a lock, maybe to control access to that variable. If another thread uses that same instance of A and tries to run a.methodA(), it will be blocked until methodB() is over.
So using an intrinsic monitor exposes the synchronization policy and can lead to subtle bugs and performance issues.
public class A {
public synchronized void methodA() {}
}
public class B {
A a = new A();
public void methodB() {
synchronized(a) {
// do something a little long
}
}
public A getA() {return a;}
}
If A had used an internal monitor that problem would not be possible.
public class A {
private final Object lock = new Object();
public void methodA() {
synchronized(lock) {}
}
}
Another scenario where using ad hoc monitors makes sense is when a class contains 2 (or more) unrelated objects, that both need to be accessed in a synchronized manner. Using 2 monitors instead of one reduces contention as the 2 objects can now be accessed concurrently.
public class SyncTest{
private Object obj = new Object();
public void func1() {
synchronized(obj) {
obj.something();
}
}
Yes it can be done.
The synchronize block will use that object as a lock, rather than the whole class. People that use synchronized(this) { } put an exclusive lock on the whole object, which might be what you want. However, you might have something like a persister, which is the only thing that needs to be synchronized. synchronized(persister) { }, would provide a less granular way of doing this.
In Java, you can use synchronized constructs to create instrinsic locks on any object reference, yes. Read the relevant Java Tutorial.
The immediate example of not using synchronized with this is when synchronizing on the Class object, which is how static synchronized methods work. In reality, there are plenty of valid uses. You may want to avoid using synchronized (this) in favor of an internal implementation lock as otherwise you are setting a restriction that you use the lock internally, which other code you're not aware of might violate.
You should know, however, that often times you can replace synchronized usage with a ReentrantLock. You can read more about this in my post here.