I am reading the book, "Core Java I" written by Cay H. Hostmann and he gives some information about the threads. He gives an example about threads and he gives a concrete banking example. As you know, in a bank, you may transfer funds, and he imagined that one fund transfer has implemented by one thread. At page 571 he wrote:
If the transfer method finds that sufficient funds are not available, it calls
"sufficientFunds.await();"
The current thread is now deactivated and gives up the lock. This lets in another thread that can, we hope, increase the account balance.
There is an essential difference between a thread that is waiting to acquire a lock and a thread that has called await. Once a thread calls the await method, it enters a wait set for that condition. The thread is not made runnable when the lock is available. Instead, it stays deactivated until another thread has called the signalAll method on the same condition. When another thread has transferred money, it should call
sufficientFunds.signalAll();
This call reactivates all
threads waiting for the condition. When the threads are removed from the wait set, they are again runnable and the scheduler will eventually activate them again. At that time, they will attempt to
reenter the object. As soon as the lock is available, one of them will acquire the lock and continue where it left off, returning from the call to await.
In the last paragraph, he mentioned: "reenter the object" (in bold). What does he mean? Also, he mentioned "returning from the call to await." Does he mean that the thread will start off from the point where await function calls?
Thanks in advance.
By “re-enter the object” he means the threads will try to execute the methods on the object (that are protected by the lock).
And yes, at the point it is signaled the waiting thread is still executing the await method, it never went anywhere. The thread went into a wait state where it doesn’t get scheduled to run, getting signaled wakes it up, then it has to acquire the lock in order to leave the await method.
Related
I am new to OS/multithreading and I'm wondering how wait() and notify() work together. I just saw this: Producer Consumer Solution in Java
And I'm kind of confused. Let's say I called wait() in PC.consume() method. When I reach the line that says notify() in PC.produce(), how does this wait in PC.consume() know that THAT is the one being notified? There could be other places that could be notified so how does it exactly know which to notify?
Thanks!
Wait and notify are called on the same object, the one being used as a lock (in the example that’s the object referenced by the local variable pc). The term used in the javadoc (here is the start of the api doc for the notify method) is “monitor”:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The OS has a thread scheduler that is making the arbitrary decision described in the javadoc, it decides things like when threads get context-switched or who gets notified.
So when a thread in consume waits, it goes dormant. Then eventually some other thread (in the example there are only two threads that acquire the lock on pc) calls notify on the same object the first thread called wait on, the scheduler picks the thread to be notified (has to be the first thread here because nothing else is waiting), and the notified thread wakes up and checks if there is anything to consume so it can know whether to proceed.
Under what conditions can this happen?
As far as I know
Blocked queue is a buffer between threads producing objects and consuming objects.
Wait queue prevents threads from competing for the same lock.
So thread gets a lock, but is unable to be passed onto consumer as it is now busy?
The question makes only sense under the assumption that it actually means “What circumstances can cause a thread to change from the wait state to the blocked state?”
There might be a particular scheduler implementation maintaining these threads in a dedicated queue, having to move threads from one queue to another upon these state changes and influencing the mind set of whoever originally formulated the question, but such a question shouldn’t be loaded with assumed implementation details. As a side note, while a queue of runnable threads would make sense, I can’t imagine a real reason to put blocked or waiting threads into a (global) queue.
If this is the original intention of the question, it should not be confused with Java classes implementing queues and having similar sounding names.
A thread is in the blocked state if it tries to enter a synchronized method or code fragment while another thread owns the object monitor. From there, the thread will turn to the runnable state if the owner releases the monitor and the blocked thread succeeds in acquiring the monitor
A thread is in the waiting state if performs an explicit action that can only proceed, if another thread performs an associated action, i.e. if the thread calls wait on an object, it can only proceed when another thread calls notify on the same object. If the thread calls LockSupport.park(), another thread has to call LockSupport.unpark() with that thread as argument. When it calls join on another thread, that thread must end its execution to end the wait. The waiting state may also end due to interruption or spuriuos wakeups.
As a special case, Java considers threads to be in the timed_waiting state, if they called the methods mentioned above with a timeout or when it executes Thread.sleep. This state only differs from the waiting state in that the state might also end due to elapsed time.
When a thread calls wait on an object, it must own the object’s monitor, i.e. be inside a synchronized method or code block. The monitor is released upon this call and reacquired when returning. When it can’t be reacquired immediately, the thread will go from the waiting or timed_waiting state to the blocked state.
Synchronized blocks in Java is a great feature when working in multiple threads, which is pretty often. I know most of how they work, but would like to be more sure of how they work when combined with wait and notify(All).
Normally when one thread enters an synchronized block, no other thread can enter this block until the first thread has left. This however is not the case when calling wait on the synchronized object. If it did, another thread would not be able to call notify(All), which requires synchronization with the object before it is called.
So does the call to wait take the call out of the synchronization? Or does java just make an exception if it finds notify(All) within a different block? Also when calling wait from one synchronized block and then notify(All) from another, does one thread wait for the other to finish before continuing, if so, which one?
Now I could setup a quick test to answer most of this, that I am aware of. But it is not going to answer the more technical stuff, which I am sure that someone here can. I am not just interested in the what and when, but also the why. Tried searching for some documented info, but could not find anything useful about wait/notify(All).
EDIT:
If others should be interested, this is the test result. If we have Thread1, Thread2 and Thread3 where the first two waits to be release and the third is the one to release them, the order will go like this.
Thread1 enters and calls wait()
Thread2 enters and calls wait()
Thread3 enters and calls notifyAll()
Thread3 finishes, always
The waiting threads however has no specific order. Which one is executed first, is completly random and has nothing to do with the order in which they called wait(). The thread calling notify(All) however will always finish before any waiting threads continues.
Yes, it is somehow special. wait releases the lock acquired in the synchronized block and and suspends it's thread (the thread that acquired the lock) which means other threads will be allowed to acquire the lock and modify the state.
Now notify or notifyAll will wake up the thread/s that were asleep and they reacquire the lock
I'd like to check if my reasoning is correct.
First of all, I should provide a few details about the problem I'm trying to solve. A thread (part of a program) does the following things:
it starts
it calls Thread.sleep (20ms)
it calls getIn() method
it tries to get a lock (lock.lock())
if successfully gets the lock it calls Thread.sleep (100ms)
if the lock is not available it calls waitingCond.await()
after calling Thread.sleep (100ms) it calls lock.unlock()
it calls another method getOut()
it terminates (thread.join())
Given that, the following is my guessing about the thread state:
READY TO RUN state
TIMED WAITING state
WAITING state
WAITING state
BLOCKED state
WAITING state
WAITING state
TERMINATED state
Thanks
First of all, the state you describe with READY TO RUN is actually RUNNABLE. For my bachelor thesis I had created a transition graph showing the different thread states and when they ought to change. You haven't described the semantics of getIn(), so I guess it is just a random method.
If the thread is executing code, for instance on of your methods getIn() or getOut() it is RUNNABLE and not WAITING. BLOCKED is actually only a very short transition state, which is always entered when a thread tries to claim a lock. If the lock is not available the thread keeps being blocked and cannot execute another action as you imply in step 6. Also it cannot invoke a method after calling Thread.sleep() it has to wait, until the time is elapsed.
I would correct it the following way:
RUNNABLE
TIMED WAITING
RUNNABLE
BLOCKED
TIMED WAITING
BLOCKED
RUNNABLE
TERMINATED
Disclaimer: There is no guarantee for the transitions. It might even be, that a JVM vendor decides to implement the underlying mechanics in another way, for instance it could implementing blocking by spin-waiting.
If you want to dive deeper into this topic use a Profiler to find out the states of your thread. I have written one of my own to detect those states: Java Concurrency Profiler, but there are others out there as well, for instance VisualVM or YourKit.
I am going through a java 6 book. A sample code snippet is given below from Threads chapter, where I need a clarification
synchronized(a){ //The thread gets the lock on 'a'
a.wait(2000);// Thread releases the lock and waits for notify only for maximum of two seconds, then goes back to runnable state
//The thread reacquires the lock
//More instructions here
}
Now my doubt is, after 2 seconds of wait time, to continue further code execution, the above code would require the lock on object 'a' and there is fair chance that the other thread (which is supposed to call notify() on a) might already be holding a lock on it.
So shouldn't the thread go to Blocking state after 2seconds wait, instead of Runnable state as mentioned above in the comments (in Line No. 2).
If another thread has the lock on the object, then yes, you are correct, it will wait. The javadocs for wait state the following behavior when the specified amount of time elapses.
"The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked"