Hi my question is how synchronization works?
In simple words we know that if a thread entered in a synchronization block by acquiring lock on any reference, than no other thread acquire that lock until first one exit from synchronized block.
But my question is if the thread acquired a lock on a reference and execute methodA() in that method there is a synchronized block, than can other thread acquire a lock on same reference and execute methodB(), there is also a synchronized block in it?
Synchronization is for mutual exclusion
Whenever you synchronize on an object, a lock is obtained on the monitor of that object.
Image Source: Thread synchronization
As the image shows as whenever a thread acquires a lock on monitor then it becomes the owner thread and no other thread can obtain lock on same monitor unless the owner thread enters wait state or releases the lock.
That said another point to keep in mind is that locks that are used in synchronized blocks are Reentrant, which means that if Thread 1 is the owner of the lock and same thread again tries to gain lock of which it is owner then Java will allow that.
Ok, than i have a issue. synchronized(b){ try{ b.wait();
}catch(InterruptedException e){} now as i acquired a lock on b object,
it means no other thread can acquire a lock on b object.
On calling wait(), the owner thread releases the lock and goes in Wait Set as shown in diagram. After that someone else from Entry set can get the lock.
I believe that the second lock will have to wait till the first lock has been released.
Have a look at the link Java synchronized references for more information.
Synchronization is very simple
One Thread locks any number of objects.
Only one thread can lock a given object at a given time.
When attempting to lock an object that is already locked by another thread, a thread has to wait until the object is released.
A Thread in wait state releases the locks it holds until it exists the wait state (at which time it attempts to reacquire the locks previously held).
In java, a lock is acquired using a synchronized block.
To answer your question: 2 threads can never acquire a lock on the same object at the same time.
Related
synchronized (lockObject) {
// update some value of the common shared resource
lockObject.wait();
}
As on call of the wait() method, the thread will release the lock, I want to know after releasing the lock does it also update the value in the main memory of the shared resource object or it only updates the value after the execution of the synchronized block.
It is a fallacy to think that due to synchronization (e.g. synchronized or volatile) data needs to be written to main memory. CPU caches on modern CPUs are always coherent due to the cache coherence protocol.
An object.wait causes the thread to release the lock. And as soon as another thread sends a notify, the lock is reacquired. The object.wait has no semantics in the Java memory model; only acquire and release of the lock are relevant.
So in your particular case, if a thread does a wait, it triggers a lock release. If another thread would read that state after acquiring the same lock, then there is a happens-before edge between the thread that did the release of the lock (due to wait) and the thread that acquired the lock. And therefore the second thread is guaranteed to see the changes of the first.
In the JLS 17.4.5 it says
The wait methods of class Object (§17.2.1) have lock and unlock actions associated with them; their happens-before relationships are defined by these associated actions.
Also, from JLS 17.4.4:
An unlock action on monitor m synchronizes-with all subsequent lock actions on m (where "subsequent" is defined according to the synchronization order).
If a thread waits it gives up the lock so that other threads can act. It only makes sense that any changes the thread made before waiting (which triggers an unlock action) should be visible to other threads acquiring the lock.
How does the java thread acquire a lock on a monitor used in synchronized block or monitor used in synchronized methods?
I read on multiple posts that in case of biased locking this information is stored in the object header using CAS operation and in case of contended situation wait set queue/ monitor queue is used but eventually lock marked in the object header only.
If this is the case then how is lock released? How object is marked free for acquiring a lock by another thread? are wait and notify methods used internally for this? If this is the case then why is making monitor null inside the synchronized block does not throw any exception.
The below example works perfectly fine, I was expecting NullPointerException assuming the end of the synchronized block will try to mark lock property to free the lock.
Example:
Object monitor = new Object();
synchronized (monitor){
System.out.println("before null");
monitor =null;
System.out.println("after null");
}
System.out.println("successfully Exited");
In case of biased locking: if the lock is biased towards a certain thread, no CAS is needed; just a volatile write. Biased lock information is kept in the mark word of the object header. Biased locking is going to be removed from JDK 15.
If a lock is contended, the object-monitor is used for synchronization. By default the object monitor is deflated, but if there is contention or you do a wait/notify, then the monitor gets inflated and is attached to the object.
On Linux blocking behavior is implemented using a wait-queue. So when a thread needs to wait for a lock, it is removed from the scheduler and added to the wait queue. When a lock unlocks, the thread on the wait queue is reinserted back into the scheduler.
The reason why the code doesn't throw an exception is that the monitor is read only once when the synchronized block is entered.
PS: It could be that your lock get completely removed due to lock elision. If the JIT can provide no other thread can acquire that lock, there is no point in synchronizing.
Java thread can be held by either:
Unable to obtain a lock.
Being held by a wait() method.
What is the difference between the above two scenarios in terms of the Java thread state?
Consider the following simple code:
synchronized(object) {
object.wait();
System.out.println("Completed.");
}
If two threads (say ThreadA and ThreadB) are all being held at the wait() method. When another thread calls notifyAll(), ThreadA will revive from wait and obtain the lock on object and continue, for example. ThreadB will also revive but unable to get the lock on object and be held until ThreadA exits the synchronized block. ThreadB then obtains the lock and continue.
The result will be two "Completed" are printed.
In this example, there must be a time when ThreadB changes from "Being held by wait()" to "Being held because it is unable to get the lock on object".
I want to know how it works internally in Java. Please help.
Difference between being in object.wait() state and waiting for the lock on monitor of object is that thread in the object.wait() state releases all the monitor of object held by it, and it will compete with all the threads in the system to reacquire the monitors again. That makes wait() a special state.
So in your case when A and B (Thread A and Thread B) are in wait state, they don't have the monitor for synchronization object, both of them have been suspended from execution till some other thread calls object.notify() or object.notifyAll(). When the notifyAll() is called JVM wakes up all the threads (in this case A and B) in object.wait() state and they compete to get the monitor of the current synchronized block. If notify() is called then JVM picks up a A or B randomly.
It's to be noted here that JVM is not notifying any specific thread, that's why every waiting thread has to wait in a while(notify_condition_for_me) loop, that validates if the the wait condition has been if not it has to go in the object.wait() state again.
So the correct code should be
synchronized(object) {
while(myResourceArrived) {//like URL data, JDBC data or something
object.wait();
}
System.out.println("Completed.");
}
When A and B are in object.wait() state, they have released all the monitors they previously held for object, so any other thread which is waiting outside the synchronized block will be immediately able to enter the block by acquiring the released monitor of object.
Take a look at Thread.State and more specifically the WAITING and BLOCKED states.
If you are interested in the internal implementation, both can be achieved using LockSupport.park() and LockSupport.unpark(Thread), and that's actually how they are implemented in most places.
P.S. In case you are interested, here are the OpenJDK park() implementations for Windows (line 4946) and Linux (line 5808), and here is the wait()/notify()/notifyAll() implementation (line 1457). They are very well commented, just give it some time if it all looks too complicated on first glance.
I am investigating Java concurrency and I've found one interesting question which I cannot answer.
For example, I have three threads: ThreadA, ThreadB and ThreadC. ThreadA enters the monitor, and invokes method wait(). Then ThreadB enters the same monitor, invokes method notify() and continue owning the monitor during some period of time. While ThreadB is owning the monitor, ThreadC tries to acquire the monitor too. My question is whether ThreadC can acquire the monitor earlier then ThreadA when ThreadB release it or not? If it can, why? Which conditions should be followed to reproduce it?
As per the Javadoc on Object.notify():
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
So there exists the possibility that ThreadC owns the monitor before ThreadA. There is no defined order in which any of the threads enter/obtain the monitor, nor is there any priority or fairness mechanism in place for standard synchronization. All it really guarantees is that for a given lock object, only on thread will be in the synchronized block at once.
Given this fact, careful design considerations should go into how threads obtain the lock and for how long. A thread that repeatedly attempts to acquire a lock (acquire and then release but then acquire again) can cause another thread to be locked out indefinitely (called thread starvation).
Using ReentrantLock with a fairness policy can partially overcome this issue at some performance cost (its slightly slower than traditional synchronization).
Suppose d is the object we're using to invoke wait. When a thread invokes d.wait, it must own the intrinsic lock for d — otherwise an error is thrown. Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock.
so is this means that two threads cannot invoke wait() at the same time? what do intrinsic lock here mean [mentioned it as Monitor]? but how 's monitor implemented to achive mutual exclusion?
once the thread invokes wait does it holds object forever?
if so how about other thread using that lock for notifyAll()?
if we need to acquire object during notifyall, then why all waiting threads notified?
shouldn't it notify threads waiting on that object alone?
Any code to explain is appreciated.
so is this means that two threads cannot invoke wait() at the same
time?
Correct two thread cannot invoke wait() at the same time. However, once one thread is in wait(), another thread can acquire the same lock and enter a wait() state soon after. You can have any number of threads WAITING on the same object, but only one really holds the lock.
what do intrinsic lock here mean [mentioned it as Monitor]? but
how 's monitor implemented to achive mutual exclusion?
Only one thread can be running while holding a object. Other thread can be blocking trying to acquire the lock and more can be wait()ing on it.
once the thread invokes wait does it holds object forever?
The opposite, it gives it up or another thread can acquire it almost immediately.
if so how
about other thread using that lock for notifyAll()?
If you call notifyAll() on the object, all the wait()ing thread are woken in turn. Those threads can only acquire the lock one at a time and will re-acquire the lock as soonas they can.
if we need to acquire object during notifyall, then why all waiting
threads notified?
That is what notifyAll does, it is considered safer than using notify, which wakes a random one as it is less prone to coding errors.
shouldn't it notify threads waiting on that object alone?
That is what it does.
You should note that;
before you notify()/notifyAll() you should perform a state change. You should also wait() inside a loop which checks that state change. You need to do this because a) wait() can miss a notify(), b) it can wake spuriously c) another thread might grab whatever you ahve done and it might need to wait again.
over the last 9 years, there has been greater use of High Level concurrency classes. Using these classes mean you don't need to work with Threads, Queues, wait() and notify() directly.
Invoking wait inside a synchronized method is a simple way to acquire
the intrinsic lock.
Wait does not provide the lock on an object rather it makes the thread to wait to listen about the lock release when other thread calls notify. Thread gets the lock when it enters the guarded//synchronized block. Synchronzied block/method allows to take the lock if available otherwise thread cannot enter those code block.
Locks are not held forever, according to the javadoc:
The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
When you call wait(), you release the intrinsic lock on that object, until another thread calls notify() or notifyAll() on it. At that point, the JVM will wake one of the threads waiting, and automatically reacquire the lock on that object.
So to answer your question, yes, multiple threads can wait() on the same object.