亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java `wait()` 等待是如何實現的?

java `wait()` 等待是如何實現的?

素胚勾勒不出你 2022-05-12 15:02:25
我問的是等待過程而不是訪問排序方法,它是最簡單的形式,是帶有條件退出的無限循環。什么是等待請求的資源消耗最少的方式,這就是讓我問這個的原因。
查看完整描述

3 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

Object.wait()JVM_MonitorWait根據ThreadReferencejavadoc ,功能是使用本機方法實現的:


/** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */

public final int THREAD_STATUS_WAIT = 4;

該方法的實現可以在jvm.cppand 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實現是 insynchronizer.cpp并委托給ObjectMonitor::waitin objectMonitor.cpp。


如果您繼續深入研究,您最終將獲得依賴于平臺的本機 Java 線程實現。在 Linux 上libpthread.so,這將最終處理線程狀態的變化。


查看完整回答
反對 回復 2022-05-12
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

最簡單的形式是帶條件退出的無限循環嗎?

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

細節很復雜并且取決于系統(請參閱@Karol 的代碼鏈接的答案),但一般方法如下。

當線程調用wait()時,該方法執行以下操作:

  1. 將線程詳細信息添加到互斥對象的“等待對象”隊列中。

  2. 放棄線程的互斥鎖。

  3. 通過告訴操作系統使其進入睡眠狀態來“停放”線程。

  4. 操作系統找到一些其他線程來調度。如果沒有,它會導致核心進入低功耗“空閑”循環或暫停它或其他東西。(這取決于操作系統和硬件。)

然后當另一個線程調用時notify, notify 方法執行以下操作:

  1. 它從互斥隊列中刪除一個線程。

  2. 它告訴操作系統應該喚醒(以前)等待的線程。

  3. 它從notify()調用中返回并(希望)釋放互斥鎖。

操作系統執行以下操作:

  1. 它找到一個空閑的處理器來運行線程,然后啟動。

  2. 如果沒有可用的內核,操作系統會將線程添加到調度程序的可運行線程隊列中。

  3. 當線程啟動時,它首先嘗試重新獲取互斥鎖......如果其他線程仍然持有鎖,這可能會導致它重新進入睡眠狀態。

  4. 最后wait調用返回,線程通常會重新檢查條件變量,然后釋放鎖。

關鍵是(通常)沒有在線程等待時消耗 CPU 的無限循環。


什么是等待請求的資源消耗最少的方式,這就是讓我問這個的原因。

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


查看完整回答
反對 回復 2022-05-12
?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

在同步編程中,監視器可以被假設為一個盒子,或者更具體地說是一個控制盒(用于對對象進行任何更改),在任何給定時刻只有一個線程的空間。因此,可以防止多個線程同時寫入一個對象并保護對象不被損壞。在其中,wait() 方法告訴一個線程,如果任何其他線程已經在監視器中,如果是,則告訴調用線程等待其他線程出來。或者從技術上講,告訴調用線程 SLEEP 直到收到通知。

它停止調用線程中代碼的任何進一步執行,這與無限循環不同,在無限循環中,執行繼續,但循環之后沒有代碼執行,直到循環中斷。


查看完整回答
反對 回復 2022-05-12
  • 3 回答
  • 0 關注
  • 198 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號