Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

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.

like image 249
green_dust Avatar asked Oct 16 '25 04:10

green_dust


2 Answers

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.

like image 129
Karol Dowbecki Avatar answered Oct 18 '25 18:10

Karol Dowbecki


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:

  1. Add the thread details to the mutex object's queue of "objects waiting".
  2. Relinquish the thread's mutex lock.
  3. "Park" the thread by telling the OS to put it to sleep.
  4. 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:

  1. It removes a thread from the mutex queue.
  2. It tells the OS that the (previously) waiting thread should be woken.
  3. It returns from the notify() call and (hopefully) releases the mutex lock.

The OS does the following:

  1. It finds a free processor to run the thread, and starts.
  2. If no core is free, the OS adds the thread to the scheduler's queue of runnable threads.
  3. 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.
  4. 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 ...

like image 33
Stephen C Avatar answered Oct 18 '25 17:10

Stephen C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!