Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java`wait()`waiting是如何实现的?_Java - Fatal编程技术网

java`wait()`waiting是如何实现的?

java`wait()`waiting是如何实现的?,java,Java,我问的是等待过程而不是访问排序方法,它是一个具有条件出口的无限循环的最简单形式 等待请求最省力的方式是什么?这正是我提出这个问题的原因。功能是通过JVM\u MonitorWait本机方法实现的,如ThreadReferencejavadoc: /** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */ public final int THREAD_STATUS_WAIT = 4; 此方法的实现可以在中找到

我问的是等待过程而不是访问排序方法,它是一个具有条件出口的无限循环的最简单形式

等待请求最省力的方式是什么?这正是我提出这个问题的原因。

功能是通过
JVM\u MonitorWait
本机方法实现的,如
ThreadReference
javadoc:

/** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */
public final int THREAD_STATUS_WAIT = 4;
此方法的实现可以在中找到并使用
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
实现在中,并委托给
ObjectMonitor::wait
在中

如果您继续深入研究,最终将获得依赖于平台的本机Java线程实现。在Linux上,这将是
libpthread.so
,它将最终处理线程状态的更改

它是一个具有条件出口的无限循环的最简单形式吗

不,不是。这是低效的,而不是通常的做法

细节复杂且依赖于系统(参见@Karol的答案以获取代码链接),但一般方法如下

当线程调用
wait()
时,该方法执行以下操作:

  • 将线程详细信息添加到互斥对象的“正在等待的对象”队列中
  • 放弃线程的互斥锁
  • 通过告诉操作系统将线程置于睡眠状态来“停止”线程
  • 操作系统会找到其他要调度的线程。如果没有,则会导致内核进入低功耗“空闲”循环或暂停它或其他。(这取决于操作系统和硬件。)
  • 然后,当另一个线程调用
    notify
    时,notify方法执行以下操作:

  • 它从互斥队列中删除一个线程
  • 它告诉操作系统应该唤醒(以前)等待的线程
  • 它从
    notify()
    调用返回,并(希望)释放互斥锁
  • 操作系统执行以下操作:

  • 它找到一个空闲的处理器来运行线程,然后启动
  • 如果没有可用的内核,操作系统会将线程添加到调度程序的可运行线程队列中
  • 当线程启动时,它首先尝试重新获取互斥锁。。。这可能会导致它重新进入睡眠状态,如果其他线程仍然持有锁
  • 最后,
    wait
    调用返回,线程通常会重新检查条件变量,然后释放锁
  • 关键是(通常)在线程等待时不存在消耗CPU的无限循环


    等待请求的最省力的方式是什么?这正是我提出这个问题的原因


    资源消耗最少的方式是
    Object.wait
    Object.notify

    在同步编程中,监视器可以假设为一个盒子,或者更具体地说是一个控制盒子(用于对对象进行任何更改),在任何给定的瞬间只有一个线程的空间。因此,可以防止多个线程同时写入一个对象,并防止对象损坏。在其中,wait()方法告诉一个线程,如果监视器中已经有其他线程,如果有,告诉调用线程等待其他线程出现。或者从技术上讲,告诉调用线程在收到通知之前休眠


    它会停止调用线程中任何进一步的代码执行,这与无限循环不同,在无限循环中,执行将继续,但在循环结束之前,不会执行循环后的代码。

    我希望这会有所帮助:)