Thread.yield原理分析

Thread.yield()方法的作用是暫時放棄當前線程對CPU的佔用權,將它讓給其它線程。他是如何實現的呢?通過看yield源碼,發現其是本地方法,找到其在JVM中的源碼實現如下:

JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
  JVMWrapper("JVM_Yield");
  //判斷操作系統是否允許使用Yield,默認是false
  if (os::dont_yield()) return;
  HOTSPOT_THREAD_YIELD();

  // When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
  // Critical for similar threading behaviour
  //判斷,根據字面意思,就是說是否允許把Yield操作轉換爲Sleep操作(默認是false),如果允許的,則調用操作系統的sleep方法,如果不允許,則調用操作系統的naked_yield方法。
  if (ConvertYieldToSleep) {
    os::sleep(thread, MinSleepInterval, false);
  } else {
    os::naked_yield();
  }
JVM_END

從源碼中可以看到,yield的實現,分爲兩種,如果允許把Yield操作轉換爲Sleep操作(默認是false),則調用操作系統的sleep方法,如果不允許,則調用操作系統的naked_yield方法。

如果調用Sleep方法,這個我們都比較熟悉了,其就是讓當前線程睡眠一段時間,來實現釋放CPU的佔有的效果,這裏睡眠時間爲最小睡眠間隔,爲1MS。

如果是調用naked_yield,naked_yield方法在linux中的實現如下:

void os::naked_yield() {
  sched_yield();
}

其中sched_yield是操作系統的線程調度方法。

那sleep和sched_yield到底有什麼區別呢?
sleep:讓當前線程睡眠一段時間,睡眠期間釋放CPU的佔有權,時間到了之後,重新搶佔CPU。
sched_yield:會讓當前線程讓出CPU佔有權,然後把線程加入到同等優先級隊列的末尾,然後讓另一個級別等於或高於當前線程的線程先運行。如果沒有符合條件的線程,那麼這個函數將會立刻返回然後繼續執行當前線程的程序。
所以,sleep,一定會釋放當前線程的CPU佔用權。而sched_yield,只有當有其他線程的優先級等於或者高於當前線程的情況下,纔會讓出CPU佔有權。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章