My understanding of Java synchronized() blocks is that, if a thread already owns a lock on an object, it can enter a different block synchronized on the same object (re-entrant synchronization). Underneath, I believe that the JVM uses a reference count to increment/decrement the number of times a thread has acquired a lock, and that the lock is only released when the count is zero.
So my question is, if one encounters a piece of code that looks like this:
synchronized(this)
{
if (condition == WAITING)
{
synchronized(this)
{
condition = COMPLETE;
notify();
try
{
wait();
}
catch(InterruptedException e)
{
}
}
}
else
condition = READY;
}
what specifically happens when wait() is called? Does it merely decrement the count, or does it release the lock regardless of the count?
In the first case, it seems to me that it will produce a deadlock if lock re-entry had occurred, because it will still own the lock and would thus wait forever on another thread which is waiting on it.
In the second case, I can't really see what the point of the second synchronized block is at all.
The documentation for wait() says
"The current thread must own this object's monitor. 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,"
so I think that the second case is the correct one, but I could be wrong. So am I missing something, or have I merely come across a redundant synchronized block that could just as easily be removed from the code?
There's nothing that necessitates the reacquiring of the lock after the if.
The wait() will also release the lock completely (otherwise it would be quite deadlock prone).
The only reason for the second synchronized that I can see, is that it previously used another object and someone modified it to use the same this by mistake.
Related
I have a small question that makes me a little confused.
This is my code:
public synchronized void P() {
while(!_state) {
this.wait();
}
_state = false;
}
This method is responsible for taking semaphore.
Why it is not possible to build binary semaphore with if statement instead of while loop?
The oracle docs says:
First, 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.
So exactly only one thread should be inside the P() method -> so only one thread should be blocked on wait() method. Rest of threads should be blocked on P() method level. But when I am replacing while() for if() it does not work properly
Why it is not possible to build binary semaphore with if statement instead of while loop?
For a deep answer, you should work through Oracle's Guarded Blocks tutorial.
The shorter answer is, there's a couple of reasons why _state could be false when the wait() call returns:
Multiple consumers: It generally is safer to wake sleepers with notifyAll() instead of notify(), and if you write a program in which two or more threads could call the P() function, you probably only want one of them to be allowed to proceed when some other thread calls the V() function. So, if they all "wake up", you'll want just one to set _state=false; and you'll want the others to go back to sleep.
The same object is getting notifyAll() calls for more than one reason. It's not good practice, but it happens, especially in projects where many developers contribute to the code. In that case, you don't wan the P() call to return if the object was notified for the wrong reason. You want it to go back and continue waiting.
The documentation for o.wait() says that it is allowed to return even when object o has not been notified at all. This is known as "spurious wakeup." It happens rarely, and only in some operating systems, but they allow it because it enables a more efficient implementation of wait() and notify().
synchronized method is equivalent to synchronized(this) block.
Only 1 thread is allowed to enter synchronized block. By entering it, thread aquires lock. When you wait inside sync block, you release the lock (object monitor) and park current thread. At this moment, another thread is allowed to enter that block. Execution will continue when other thread will invoke notify or notifyAll on the same object that wait was invoked. Notified thread will "exit wait state" when given sync block's lock will be released.
To sum up - wait does not work like you expect, it does not block execution, only puts waiting thread to sleep, allowing other threads to aquire sync lock.
So you cannot do what you want to achieve, because wait works differently then you expect. What you want to use here, is ReentrantLock. https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
I have a simple program which I am finding very confusing. The code snippet is as follows:
class Processor{
public void produce() Throws InterruptedException{
synchronized(this){
System.out.println("Producer Running...");
wait();
System.out.println("Resumed");
}
}
public void consume() Throws InterruptedException{
synchronized(this){
Thread.Sleep(2000);
System.out.println("Consumer Running... Press return key to return");
scan.nextLine();
notify();
Thread.sleep(5000);
}
}
Now my question is that , when we call wait() in the "produce" method the execution is immediately transferred to the "consume" method. (produce and consume are executed in separate threads). But when the notify(); is called in the "consume " method ,the execution does not immediately transfer. It waits for Thread.sleep(5000) to complete . why is this so ?
Well, the reason is quite simple.
When a thread calls wait() on certain object it goes into a waiting state and it stops executing (it is removed from scheduling). When waiting a thread releases all the monitors it has taken (and it needs to regain them after waking up)
When a thread calls notify() on certain object it wakes up another thread waiting over it, but it does not go into a waiting state itself, so it keeps running.
After your producer thread calls notify it keeps running and performing a five seconds sleep. While sleeping a thread retains all monitors that it has taken (you are inside a synchronized(this) block hence you have a monitor for "this" object). Scheduler cannot run the consumer thread that was just notified since it needs to readquire the monitor before resuming, and it wont be freed until your producer thread stops sleeping and gets out of the synchronized block
Although you seem to be missing some code needed for me to explain completely accurately, I'll do my best to provide an explanation that would be applicable even if my guess was incorrect.
wait() and notify() are methods called on a mutex object -- in this case, this.
wait() causes the currently executing thread to pause and give up that mutex (I think it's just the mutex that wait() is called on, could be all of them. Not sure), after which another thread can acquire the mutex and start executing. This is why you observe an immediate transfer of control when wait() is executed.
When notify() is called on a mutex, a thread waiting on that mutex wakes up and attempts to acquire the lock. However, it cannot do so until the lock is available -- in this case, until the lock (this) is released by the thread that calls notify() (the consumer thread). The mutex is only released once the consumer thread exits from the synchronized block, which is after the Thread.sleep(5000); call in your code. sleep() does not release any mutexes that the current thread has acquired, so the first thread has to wait until the second has finished sleeping and exited the synchronized block.
That is why wait() transfers control immediately, while notify() (in this case) has the currently executing thread finish its method before the formerly waiting thread can continue execution.
Assuming that you are calling both methods using the same object from difference threads.
If you want to don't wait 5000 miliseconds, use wait(5000) instead of Thread.sleep(5000).
The notify method, take one (random) previously waiting thread, that is waiting to acquire the lock (of an object) that the running/current thread has taken before, and mark it to resume as soon the current thread release the lock.
In your this case, it will release the lock and soon the Thread.sleep(5000) finish and leave the synchronized block.
Be aware, if you call produces or consume with diferents objects things will go totally diferent. I strongly suggest to read this article.
Hope it helps! As the good answers below!
The reason is that Thread.sleep(5000L) does not release the lock on the object's monitor while it's waiting, contrary to wait(5000L). This is specified in the Javadoc for Thread.sleep() :
... The thread does not lose ownership of any monitors.
Whereas the javadoc for Object.wait() specifies:
... This method causes the current thread (call it T) to place itself
in the wait set for this object and then to relinquish any and all
synchronization claims on this object...
I was getting java.lang.IllegalMonitorStateException. I referred this question and it solved my problem. The first answer is
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
My question is why we need to synchronize on the same object ad how it works?
As far as my understanding goes when we say
synchronized (someObject) {
someObject.wait();
}
we get a lock on object someObject and then we call wait() on it. Now how can another thread get lock on same object to call notify() on it? What am I missing?
Why does notify need a lock too?
Imagine this scenario:
synchronized(x){
while(x.count < 4) {
x.wait();
//...
}
}
Imagine now a notify elsewhere without any lock around it:
//...
println(x.count); // print 3
x.count++;
if(count == 4)
x.notify()
//...
At first glance, the whole sounds to always work as expected.
However, imagine this race condition:
//Thread1 enters here
synchronized(x){
while(x.count < 4) {
//condition is judged true and thread1 is about to wait
//..but..ohh!! Thread2 is prioritized just now !
//Thread2, acting on notify block side, notices that with its current count incrementation,
//count increases to 4 and therefore a notify is sent....
//but...but x is expected to wait now !!! for nothing maybe indefinitely !
x.wait();
//maybe block here indefinitely waiting for a notify that already occurred!
}
}
If only we had a way to tell this to notify side:
Thread 1: "Humm..notify, you are cute but I've just started to evaluate my condition (x.count < 4) to true, so please... don't be silly by sending your expected notification just now (before I put my status to waiting), otherwise, I would be ridiculous to wait for a thing that already passed"
Thread2: "Ok ok... I will put a lock around my logic in order to stay consistent, so that I send my notification after your wait call releases our shared lock, and thus you will receive this notif, allowing to quit your waiting status ;)"
Thus, always place a lock on the notify side, on the same object that is hold by wait, in order to avoid this situation and let the relationship always consistent.
=> A logic leading to a notify and a logic leading to a wait should never overlap.
As per the javadoc for Object#wait()
The current thread must own this object's monitor. 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.
To use wait/notify the thread must have the lock, otherwise
IllegalMonitorStateException is thrown
Throws: IllegalMonitorStateException - if the current thread is not
the owner of the object's monitor.
Why
So,
wait() makes current thread release the lock
notify() signals other waiting thread(s) which then try to acquire the lock.
For doing either, the current thread must have the lock. And it makes sense!
Edit
Why must thread calling wait() hold the lock is pretty obvious now.
But why must thread calling notify() hold the lock? Well, for one, to prove its authenticity. Otherwise any thread could keep firing false notifications and the waiting threads would keep getting interrupted. Thankfully that is not the case.
wait/notify are typically used to wait for some other thread to accomplish a task, or to wait until a certain condition is satisfied.
Lets say we have an object called objectA and two threads called thread1 and thread2.
thread1 has some thread safe task,so it acquires objectA's monitor using synchronized block.
synchronized (objectA) {
//here thread1 owns objectA's monitor
}
In java calling wait() means releasing monitors so that other threads can get this monitor and achieve its tasks and current thread goes into some state called waiting state for objectA's monitor.
synchronized(objectA){
//here thread1 owns objectA's monitor.
objectA.wait();
//here thred1 releases monitor of objectA's monitor and goes into waiting state and waits to get objectA's monitor once again to complete its task.
}
Now thread2 can own the objectA's monitor and excutes its task.
synchronized(objectA){
//here thread2 owns objectA's monitor.
//some task;
}
Once task completes it notifies the other threads in waiting state that it is released the monitor on the object it owns. please note that to call notify() also thread should be owner of object monitor.
synchronized(objectA){
//here thread2 owns objectA's monitor.
//some task;
objectA.notify();
//it signals some other thread that it can wake up from wait,so that other waiting threads can owns objectA's monitor
}
here calling wait() on objectA and calling notify() on other object(lets say objectB) is makes no use to thread1.Since thread1 waiting to get monitor on objectA not on other object(lets say objectB).
update
Why obtain monitor to call notify()
to call notify() we need to obtain monitor,because it is guaranteed that two threads trying to call notify( ) on one object won’t step on each other’s toes(to aviod race condition).
why we need to get lock before notify
Looking through the Hotspot JVM source code I found this: The notify() method modifies the wait set of the object's monitor. (The wait set of an object is the set of threads that have called wait() on it.) If the access to the wait set was not synchronized bad things could happen: for example a thread could be dropped from the set without ever being awoken. Requiring that the calling thread owns the monitor before calling notify() solves this issue, though other solutions could also exist.
There are also other arguments, such as notify being called without holding the monitor often implying a programmer error, but I don't think that's enough to motivate such a restriction.
I'm very confusing about these two descriptions:
"The wait method blocks the calling thread and gives up the monitor lock"
"The notify method unblocks one waiting thread but does not give up the monitor lock"
Here is my questions:
I know each object in Java has a lock, but what is the "monitor lock" means? is it the same as the oject's lock?
Why notify method needs to give up the monitor lock?
If I try to make a object waiting with the following code:
class simpleTask extends Thread
{
int waitingTime;
public simpleTask(int waitingTime)
{
this.waitingTime = waitingTime;
}
public void run()
{
synchronized(this) // this is a reference of current object
{
try {
this.wait(waitingTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Like the first description above, is that means the the current object is blocked by synchronized keyword, and then wait method releases the lock?
I know each object in Java has a lock, but what is the "monitor lock" means? is it the same as the object's lock?
Yes, they are the same thing. They are also occasionally called the object's "mutex" and the object's "primitive lock". (But when someone talks about Lock, they are talking about this Java interface ... which is a different locking mechanism.)
Why notify method needs to give up the monitor lock?
The notify method doesn't give up the lock. It is your code's responsibility to give up the lock (i.e. leave the synchronized block or return from the synchronized method) after the notify call returns.
Why is that necessary? Because any other thread that is currently waiting on that lock (in a wait(...) call) has to reacquire that lock before the wait call can complete.
Why did they design notify / wait like this? So that they can be used to implement condition variables.
Like the first description above, is that means the the current object is blocked by synchronized keyword, and then wait method releases the lock?
That is correct. When a thread calls someObject.wait() its lock on someObject is released ... and then reacquired (by the same thread) before the wait() call returns. Of course, in the meantime the lock someObject may have been acquired and released multiple times by other threads. The point is that when wait returns, the thread that called wait will have the lock.
Yes, the monitor lock is the same as the object's lock. If you do synchronized (object), that's the lock.
In your example, the current object will give up the lock while waiting, the wait() call gives up the lock. In another thread, notify() is called to wake the object up, and when the wait() call returns it will hold the lock again.
A monitor is a type of synchronization construct.
The reason that waiting gives up the lock is so that other threads can acquire the lock, such as other threads that might want to wait. Also: It's usual for the thread that's awakening other threads to lock before releasing any threads, to prevent a race condition.
For more about this, you should study condition variables (i.e. condvars).
Thread 1:
if(!conditionFullfiled) this.wait();
Thread 2:
if(conditionFullfiled) thread1.notify();
I want to wake up thread 1 from thread 2, when some condition is fullfiled. But isn't there a problem, when thread1.notify() is called if(!conditionFullfiled) ***HERE*** this.wait(); ?
To do obj.wait() and obj.notify(), you need to own the monitor of the object you're going to wait/notify on. In your code, you probably don't want thread1.notify(). Example:
Object someSharedObject = ...
Thread1:
synchronized(someSharedObject) {
// while NOT if for spurious wake ups.
while(!conditionFullfiled) someSharedObject.wait();
}
Thread2:
synchronized(someSharedObject) {
if(conditionFullfiled) someSharedObject.notify(); // this wakes thread1
}
The synchronized lock is on someSharedObject (can be this), which means the two threads will never clash. .wait() releases the currently held monitor, so Thread2 will not be blocked when Thread1 is waiting.
Edit: I learnt something about spurious wake ups. The .wait() must be done in a while loop - if is not enough. Why do threads spontaneously awake from wait()? . Thanks Enno Shioji for teaching me.
Edit: Clarified .wait() releases monitor.
You have 2 problems here.
you should not call wait() and notify() on thread object itself. Better way to do this is to use special lock object, e.g.
private Object lock = new Object();
......
lock.wait();
The next problem is that you have to call both wait() and notify into synchornized block, i.e.
syncronized(lock) {
// some code
lock.wait();
}
then in other place in code say:
syncronized(lock) {
lock.notify(); // this line will cause the wait to terminate and the first thread to continue.
}
It is convenient to localize both wait() and notify() wrapping methods in one class, so they have access to lock object.
For more information read
http://download.oracle.com/javase/6/docs/api/
http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html
No problem at all since wait releases object lock (in case this).
It's a best practice to guard wait/notify conditions in while blocks - to avoid spurious wake-ups.
What object you use as "this"? If you invoke wait() on thread1 object, and both statements you have shown are wrapped in a loop like this:
new Runnable() {
synchronized (thread1) {
thread1.wait()
}
}
Then your code will work as you want. (First thread will halt when condition is false, and work otherwise).
The trick is that interactions on the thread object are synchronized, so one thread can not interrupt while other is working with the object.
EDIT:
It will be even better if you will synchronize not on the thread, but on some other object (you can simply create pure object to provide locks).