How is class level locking achieved in java? - java

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.

Related

What are the impacts of using Object.class lock in synchronized block?

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.

Can a seperate thread continue execution on an object synchronised by another?

Say I have an object A which has 2 methods:
public doSomething()
{....}
public synchronised doSomethingElse()
{ ... }
and I have thread1.doSomethingElse(), will it still be possible for thread2.doSomething() to execute or is it blocked by thread1's lock?
If so, how can I make thread1 execute at the same time?
There are two types of synchronization
1. Object level
2. Class level (Class level synchronization is for the static methods only.)
In your case since your methods are not static it is object level synchronization. For object level synchronization you can either synchronize your whole methods or you can synchronize some block of your methods.
When you synchronized one method. Its mean that same object of your class cant access your synchronized method from different threads. As each object have only one lock. If you had called doSomethingElse() for same obj but from different threads. Then It will be accessible by one thread.
Now comes to your answer:
As your first method is not synchronized i.e something(). It will not be effected in any case if you call it for any no of threads or even call it when your first thread is currently in the method. Locks are only for synchronized methods
Yourclass obj = new Yourclass();
Thread A = new MyThread(obj);
Thread B = new MyThread(obj);
......
public void run()
{
\\do what ever you want
\\both of your methods will be called.
\\ call them both here.
}
here i have made objects of same Mythread class you can do as per you want. you can make objects of two different implemented thread classes and write your run. In any case it will have no effect on the call.
Since thread 2 is not attempting to acquire any lock, it is not blocked and can run concurrently with thread 1. There's nothing special you need to do.

Synchronized Block within Synchronized Method

I'm looking at some code in a third party library that contains a synchronized method, and within this method there is a synchronized block that locks on an instance variable. It's similar to this:
public class Foo {
final Bar bar = new Bar();
public synchronized void doSomething() {
// do something
synchronized(bar) {
// update bar
}
}
...
}
Does this make sense? If so, what benefits are there to having a synchronized statement within a synchronized method?
Given that a synchronized method locks on the entire object, it seems redundant to me. Perhaps this approach makes sense when working with instance variables that are not private?
In your example the method is both locking on the instance of Foo and on the object bar. Other methods may only be locking on the instance of Foo or on the object bar.
So, yes, this makes sense depending on exactly what they are doing. Presumably bar protects some smaller subset of data, and some methods will only need to lock on bar to perform their actions in a thread-safe manner.
What synchronized does
synchronized (on a method, or in a statement) creates a mutual exclusion zone (critical section or, specifically for Java, a reentrant mutex). The "key" for a thread to enter the critical section is the object reference used in the synchronized statement ‡. Only one thread can (recursively) "own" this "key" at one time across all blocks that use the same key; that is, only one thread can enter any block synchronized on a given object reference at one time.
Such a critical section simply prevents the operations (variable read/write) that you do inside the block happening concurrently with any other operations in all other critical sections that lock on the same object reference. (It doesn't automatically protect all variables inside an object).
In Java, such a critical section also creates a happens-before contract.
By example
As a somewhat contrived example †:
public class Foo {
final Bar bar = new Bar();
private int instanceCounter = 0;
private int barCounter = 0;
public synchronized void incrementBarCounterIfAllowed() {
synchronized (bar) {
if (instanceCounter < 10) barCounter++;
}
}
public synchronized void incrementClassCounter() {
instanceCounter++;
}
public void incrementBarCounter() {
synchronized (bar) {
barCounter++;
}
}
}
Whether the instance variables are private or not doesn't really matter to whether this approach is applicable. In a single class you can have multiple lock objects, each of which protect their own set of data.
However the risk of doing this is that you have to be very strict with coding conventions to prevent deadlocks by locking two locks in different orders in different places. For example, with the above code if you then do this from somewhere else in the code:
synchronized(myFoo.bar) {
myFoo.incrementClassCounter();
}
you risk a deadlock with the incrementBarCounterIfAllowed() method
† Note that barCounter could be an instance variable for Bar etc etc - I avoided that for the sake of brevity in the code sample.
‡ In the case of synchronized methods, that reference is the reference to the class instance (or to the Class<?> for the class for static methods).
When you say "synchronized method locks on the entire object", that's not true. Using synchronized only means that threads have to acquire that lock before they can enter the methods or blocks marked as synchronized that use that lock. The default object used as a lock for synchronized on instance methods is this. The default is this.getClass() if you put synchronized on a static method, or you can specify the object to use as a lock. Using synchronized doesn't do anything other than that to make instance fields inaccessible.
You can write a class where some methods or blocks are protected by one lock, some are protected by another lock, and for others you need both locks. Make sure you acquire the locks in the same order or you can cause a deadlock.
Consider this:
public void someMethod() {
synchronized(bar) {
// fully accessible before entering the other synchronized bar block
// but not afterwards
}
}
Get it clearly, synchronizing only blocks if 2 blocks synchronize on the same object.
I will give a real life example to explain what Andy explained through code(to those who are finding it difficult to understand this):
Suppose You have a 1 BHK Flat .
The way to enter in room is through hall (you have to first enter into hall to enter into room)
You want to restrict some one to use you room , but he can use/enter in the hall.
In this case if someone enters into room from back door and applies lock from inside. One can only enter into the hall and cant enter into the room until the person inside the room releases the lock .
Hope this clarifies to the people who are finding it difficult to understand this.

question about singleton classes and threads

I'm trying to learn about singleton classes and how they can be used in an application to keep it thread safe. Let's suppose you have an singleton class called IndexUpdater whose reference is obtained as follows:
public static synchronized IndexUpdater getIndexUpdater() {
if (ref == null)
// it's ok, we can call this constructor
ref = new IndexUpdater();
return ref;
}
private static IndexUpdater ref;
Let's suppose there are other methods in the class that do the actual work (update indicies, etc.). What I'm trying to understand is how accessing and using the singleton would work with two threads. Let's suppose in time 1, thread 1 gets a reference to the class, through a call like this IndexUpdater iu = IndexUpdater.getIndexUpdater(); Then,
in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton or would it be prevented as long as the first thread has an active reference to the class. I'm assuming the latter (or else how would this work?) but I'd like to make sure before I implement.
Thank you,
Elliott
Since getIndexUpdater() is a synchronized method, it only prevents threads from accessing this method (or any method protected by the same synchronizer) simultaneously. So it could be a problem if other threads are accessing the object's methods at the same time. Just keep in mind that if a thread is running a synchronized method, all other threads trying to run any synchronized methods on the same object are blocked.
More info on:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Your assumption is wrong. Synchronizing getIndexUpdater() only prevents more than one instance being created by different threads calling getIndexUpdater() at (almost) the same time.
Without synchronization the following could happen: Thread one calls getIndexUpdater(). ref is null. Thread 2 calls getIndexUpdater(). ref is still null. Outcome: ref is instantiated twice.
You are conflating the instantiation of a singleton object with its use. Synchronizing the creation of a singleton object does not guarantee that the singleton class itself is thread-safe. Here is a simple example:
public class UnsafeSingleton {
private static UnsafeSingleton singletonRef;
private Queue<Object> objects = new LinkedList<Object>();
public static synchronized UnsafeSingleton getInstance() {
if (singletonRef == null) {
singletonRef = new UnsafeSingleton();
}
return singletonRef;
}
public void put(Object o) {
objects.add(o);
}
public Object get() {
return objects.remove(o);
}
}
Two threads calling getInstance are guaranteed to get the same instance of UnsafeSingleton because synchronizing this method guarantees that singletonRef will only be set once. However, the instance that is returned is not thread safe, because (in this example) LinkedList is not a thread-safe queue. Two threads modifying this queue may result in unexpected behavior. Additional steps have to be taken to ensure that the singleton itself is thread-safe, not just its instantiation. (In this example, the queue implementation could be replaced with a LinkedBlockingQueue, for example, or the get and put methods could be marked synchronized.)
Then, in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton ...?
The answer is yes. Your assumption on how references are obtained is wrong. The second thread can obtain a reference to the Singleton. The Singleton pattern is most commonly used as a sort of pseudo-global state. As we all know, global state is generally very difficult to deal with when multiple entities are using it. In order to make your singleton thread safe you will need to use appropriate safety mechanisms such as using atomic wrapper classes like AtomicInteger or AtomicReference (etc...) or using synchronize (or Lock) to protect critical areas of code from being accessed simultaneously.
The safest is to use the enum-singleton.
public enum Singleton {
INSTANCE;
public String method1() {
...
}
public int method2() {
...
}
}
Thread-safe, serializable, lazy-loaded, etc. Only advantages !
When a second thread tries to invoke getIndexUpdater() method, it will try to obtain a so called lock, created for you when you used synchronized keyword. But since some other thread is already inside the method, it obtained the lock earlier and others (like the second thread) must wait for it.
When the first thread will finish its work, it will release the lock and the second thread will immediately take it and enter the method. To sum up, using synchronized always allows only one thread to enter guarded block - very restrictive access.
The static synchronized guarantees that only one thread can be in this method at once and any other thread attempting to access this method (or any other static synchronized method in this class) will have to wait for it to complete.
IMHO the simplest way to implement a singleton is to have a enum with one value
enum Singleton {
INSTANCE
}
This is thread safe and only creates the INSTANCE when the class is accessed.
As soon as your synchronized getter method will return the IndexUpdater instance (whether it was just created or already existed doesn't matter), it is free to be called from another thread. You should make sure your IndexUpdater is thread safe so it can be called from multiple threads at a time, or you should create an instance per thread so they won't be shared.

Java Synchronized Block for .class

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/

Categories