How is java `wait()` waiting implemented? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm asking about the waiting process not the access ordering method is it in the simplest form an infinite loop with a conditional exit.
Whats the least resource consuming way to wait for a request thats what got me to ask this.

Object.wait() functionality is implemented with JVM_MonitorWait native method, as per ThreadReference javadoc:
/** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */
public final int THREAD_STATUS_WAIT = 4;
The implementation of this method can be found in jvm.cpp and uses ObjectSynchronizer::wait:
JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
JVMWrapper("JVM_MonitorWait");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
JavaThreadInObjectWaitState jtiows(thread, ms != 0);
if (JvmtiExport::should_post_monitor_wait()) {
JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
// The current thread already owns the monitor and it has not yet
// been added to the wait queue so the current thread cannot be
// made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
// event handler cannot accidentally consume an unpark() meant for
// the ParkEvent associated with this ObjectMonitor.
}
ObjectSynchronizer::wait(obj, ms, CHECK);
JVM_END
ObjectSynchronizer::wait implementation is in synchronizer.cpp and delegates to ObjectMonitor::wait in objectMonitor.cpp.
If you continue to dig in you will eventually reach the native Java thread implementation which is platform dependent. On Linux this will be libpthread.so which will ultimately handle the thread status change.

is it in the simplest form an infinite loop with a conditional exit?
No it isn't. That is inefficient, and not how it is typically done.
The details are complicated and system dependent (see #Karol's answer for links to the code), but the general approach is as follows.
When the thread calls wait(), the method does the following:
Add the thread details to the mutex object's queue of "objects waiting".
Relinquish the thread's mutex lock.
"Park" the thread by telling the OS to put it to sleep.
The OS finds some other thread to schedule. If there is none, it causes the core to go into a low power "idle" loop or suspends it or something. (This is OS and hardware dependent.)
Then when another thread calls notify, the notify method does the following:
It removes a thread from the mutex queue.
It tells the OS that the (previously) waiting thread should be woken.
It returns from the notify() call and (hopefully) releases the mutex lock.
The OS does the following:
It finds a free processor to run the thread, and starts.
If no core is free, the OS adds the thread to the scheduler's queue of runnable threads.
When the thread starts, it first tries to reacquire the mutex lock ... which may cause it to be put back to sleep, if some other thread is still holding the lock.
Finally the wait call returns, and the thread will typically recheck the condition variable, and then release the lock.
The point is that there are (typically) no infinite loops that that consume CPU while a thread is waiting.
Whats the least resource consuming way to wait for a request that is what got me to ask this.
The least resource consuming way would be Object.wait and Object.notify ...

In synchronous programing, a monitor can be assumed like a box or more specifically a control box (to make any changes in an object) with a space of only one thread at any given instant. So, multiple threads can be prevented from writing one object at the same time and protecting the object from getting corrupted. In it, wait() method tells a thread, if any other thread is already sitting in the monitor and if so, tells the calling thread to WAIT for the other thread to come out. Or technically, tells the calling thread to SLEEP until notified.
It stops any further execution of code in the calling thread, unlike a infinite loop, in which the execution continues, but no code after the loop is executed until the loop breaks.

Related

signallAll method in threads

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.

When a Java thread performs a potentially blocking action, does it always loss the current CPU timeslice?

A potentially blocking action (e.g. Thread.join(), obj.wait(), monitorEnter ), may continue to execute under some circumstances (e.g. For Thread.join(), if the interrupt flag is set by the time of calling, the method won't block. For obj.wait(), if the interrupt flag is set and monitor is available, the action won't block). Under these circumstances, will the java thread continue in the current CPU timeslice; or will it release the current timeslice and wait for next dispatch?
Your question is a little confused - a thread can only call wait if it already owns the monitor. Which is acquired by entering a synchronised block and going through the monitorEnter process.
But to try and answer your question: if a thread invokes a potentially blocking action (i.e, needs to acquire the object monitor), will it always lose the timeslice? The answer is no. It will try a couple of "fast path" attempts first, and only then will it park the thread.
The code for monitor synchronisation is here: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp#l1192
The VM first tries a very quick atomic CAS operation to get the monitor. If that fails it tries a short spinlock (to hold the CPU). If the spinlock fails then it parks the thread.
The park happens here under Windows: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/os/windows/vm/os_windows.cpp#l4787
where it looks like it calls the Windows WaitForSingleObject API function.
There is no guarantee it will lose the CPU, nor that it will be blocked for a whole time slice if;
the operation can be performed immediately.
the operation might busy wait for a short time before giving up the CPU, but it might complete in that time.
the thread might get the CPU back within the time slice.
How this exactly work depends mostly on the OS. The busy waiting strategy is sometimes implemented in Java, in which case you will see it in the source code.
if anotherThread.join() is executed, and anotherThread has finished, there will be no loss of CPU timeslice. Similary, if monitorEnter obj is executed, and obj is not locked, execution will continue without interruption.
If you deliberately want to release the current timeslice and wait for next dispatch, then call to Thread.yield() or Thread.sleep(0), but JVM implementation may ignore your hint.

Thread.sleep and object.wait [duplicate]

This question already has answers here:
Difference between "wait()" vs "sleep()" in Java
(33 answers)
Closed 5 years ago.
Both are trying to do the similar thing, which is make some effect on thread.
I know that thread.sleep is to let the CURRENT thread to sleep and wait can let any thread to wait, if they are trying to get the object's lock.
The question is, most of the time they are doing the similar thing - what makes you choose one over another?
No, Object.wait() will only ever cause the current thread to block, too.
The main difference is that sleep() instructs the current thread to sleep for a period of time, whereas wait() instructs the current thread to release a monitor, then sleep until the monitor is notified. In other words, wait() is a coordination primitive between threads, whereas sleep() only cares about the passage of time (assuming no interruptions).
Sleep and Wait looks deciving, They differ by a lot :
Sleep - makes the Thread sleep for a given amount of time - good for Schedualing tasks, Animations and more...
Wait - mostly used without limit of time, makes one thread Wait for something to heppen, this is the best practice for synchronization.
if youre trying to Implement Wait by using Sleep, thats bad practice, which somewhat close to some very bad thing called Busy Waiting.
One is used to synchronize Threads together while the other one is used to sleep for a given amount of time.
If you want to synchronize Threads together, user wait/notify. If you want to sleep for a known amount of time, use Thread.sleep.
These two methods do very different things: Thread.sleep waits a specified amount of time while Object.wait waits for a notify event (which may take arbitrary amount of time to happen).
Both can only put the current thread to sleep. Also, Object.wait requires that the current thread is holding the monitor associated with the object.

Does thread.yield() lose the lock on object if called inside a synchronized method?

I understand that Thread.currentThread().yield() is a notification to thread scheduler that it may assign cpu cycle to some other thread of same priority if any such is present.
My question is: If current thread has got lock on some object and calls yield(), will it loses that lock right away? And when thread scheduler finds out there is no such thread to assign cpu cycle, then the thread which has called yield() will again be in fight to get lock on the object which it has lost earlier??
I couldn't find it in javadoc and forums [http://www.coderanch.com/t/226223/java-programmer-SCJP/certification/does-sleep-yield-release-lock] have 50-50 answers.
I think yield() (lets say thread1) should release lock because if some thread (lets say thread2) of same priority wants to operate on same object, then it can have chance when thread scheduler eventually assign cup to thread2.
No. Thread.yield() is not like Object.wait(). It just gives up control to allow a thread switch. It will have no effect on the concurrency of your program.
There is no guarantee which thread the scheduler will run after a yield.
In Java Language specification
17.3 Sleep and Yield
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
My comment:
In java's early days, when it did not really supported parallel executions, but only concurrent (green threads), yield() was suspending the current thread, and the jvm was picking up another thread to resume. Now-days, yield does not have much meaning as usually the tread scheduling is on OS level.
So, yield is just a hint to the JVM that current thread wants to take a rest and nothing else, it is up to the thread scheduler to decide what to do. yield does not have any synchronization semantic. If thread holds lock, it will continue to hold it.
Only wait methods of the Object class release the intrinsic lock of the current instance (the thread may have other locks acquired, they don't get released). Yield, sleep, join do not bother about locks. However, join is a little more special, you are guaranteed to see all the changes made by the thread you're waiting for to finish.

Does Yield/Join release monitor lock? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does thread.yield() lose the lock on object if called inside a synchronized method?
I know Thread.sleep() holds the lock, but Object.wait() releases the lock. Some say yield actually implements sleep(0). Does this mean yield will not release the lock?
Another question. Say the current thread has acquired a lock, and then called anotherThread.join(). Does the current thread release the lock?
Unless the javadoc mentions an object's monitor (such as Object.wait()), you should assume that any locks will continue to be held. So:
Does this mean yield will not release the lock?
Yes.
Does the current thread release the lock?
No.
sleep puts the thread in a wait state, yield returns the thread directly to the ready pool. (So if a thread yields it could go directly from running to the ready pool to getting picked by the scheduler again without ever waiting.) Neither one has anything to do with locking.
From the Java Language Specification:
Thread.sleep causes the currently executing thread to sleep
(temporarily cease execution) for the specified duration, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors, and resumption of execution
will depend on scheduling and the availability of processors on which
to execute the thread.
It is important to note that neither Thread.sleep nor Thread.yield
have any synchronization semantics. In particular, the compiler does
not have to flush writes cached in registers out to shared memory
before a call to Thread.sleep or Thread.yield, nor does the compiler
have to reload values cached in registers after a call to Thread.sleep
or Thread.yield.
For example, in the following (broken) code fragment, assume that
this.done is a non-volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse
the cached value in each execution of the loop. This would mean that
the loop would never terminate, even if another thread changed the
value of this.done.

Categories