3 回答

TA貢獻1880條經(jīng)驗 獲得超4個贊
Object.wait()JVM_MonitorWait根據(jù)ThreadReferencejavadoc ,功能是使用本機方法實現(xiàn)的:
/** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */
public final int THREAD_STATUS_WAIT = 4;
該方法的實現(xiàn)可以在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實現(xiàn)是 insynchronizer.cpp并委托給ObjectMonitor::waitin objectMonitor.cpp。
如果您繼續(xù)深入研究,您最終將獲得依賴于平臺的本機 Java 線程實現(xiàn)。在 Linux 上libpthread.so,這將最終處理線程狀態(tài)的變化。

TA貢獻1853條經(jīng)驗 獲得超9個贊
最簡單的形式是帶條件退出的無限循環(huán)嗎?
不,不是。這是低效的,而不是通常的做法。
細節(jié)很復雜并且取決于系統(tǒng)(請參閱@Karol 的代碼鏈接的答案),但一般方法如下。
當線程調用wait()
時,該方法執(zhí)行以下操作:
將線程詳細信息添加到互斥對象的“等待對象”隊列中。
放棄線程的互斥鎖。
通過告訴操作系統(tǒng)使其進入睡眠狀態(tài)來“停放”線程。
操作系統(tǒng)找到一些其他線程來調度。如果沒有,它會導致核心進入低功耗“空閑”循環(huán)或暫停它或其他東西。(這取決于操作系統(tǒng)和硬件。)
然后當另一個線程調用時notify
, notify 方法執(zhí)行以下操作:
它從互斥隊列中刪除一個線程。
它告訴操作系統(tǒng)應該喚醒(以前)等待的線程。
它從
notify()
調用中返回并(希望)釋放互斥鎖。
操作系統(tǒng)執(zhí)行以下操作:
它找到一個空閑的處理器來運行線程,然后啟動。
如果沒有可用的內核,操作系統(tǒng)會將線程添加到調度程序的可運行線程隊列中。
當線程啟動時,它首先嘗試重新獲取互斥鎖......如果其他線程仍然持有鎖,這可能會導致它重新進入睡眠狀態(tài)。
最后
wait
調用返回,線程通常會重新檢查條件變量,然后釋放鎖。
關鍵是(通常)沒有在線程等待時消耗 CPU 的無限循環(huán)。
什么是等待請求的資源消耗最少的方式,這就是讓我問這個的原因。
Object.wait
資源消耗最少的方式是Object.notify
......

TA貢獻1858條經(jīng)驗 獲得超8個贊
在同步編程中,監(jiān)視器可以被假設為一個盒子,或者更具體地說是一個控制盒(用于對對象進行任何更改),在任何給定時刻只有一個線程的空間。因此,可以防止多個線程同時寫入一個對象并保護對象不被損壞。在其中,wait() 方法告訴一個線程,如果任何其他線程已經(jīng)在監(jiān)視器中,如果是,則告訴調用線程等待其他線程出來?;蛘邚募夹g上講,告訴調用線程 SLEEP 直到收到通知。
它停止調用線程中代碼的任何進一步執(zhí)行,這與無限循環(huán)不同,在無限循環(huán)中,執(zhí)行繼續(xù),但循環(huán)之后沒有代碼執(zhí)行,直到循環(huán)中斷。
添加回答
舉報