現在の回答は最新ではないため、最近の変更を考慮して改訂が必要です。
6から9までは、Javaのバージョンに実際的な違いはありませんThread.yield()
。
TL; DR;
OpenJDKソースコードに基づく結論(http://hg.openjdk.java.net/)。
USDTプローブのHotSpotサポート(システムトレース情報はdtraceガイドで説明されています)とJVMプロパティを考慮しない場合ConvertYieldToSleep
、ソースコードyield()
はほとんど同じです。以下の説明を参照してください。
Java 9:
Thread.yield()
OS固有のメソッドを呼び出すos::naked_yield()
:
Linuxの場合:
void os::naked_yield() {
sched_yield();
}
Windowsの場合:
void os::naked_yield() {
SwitchToThread();
}
Java 8以前:
Thread.yield()
OS固有のメソッドを呼び出すos::yield()
:
Linuxの場合:
void os::yield() {
sched_yield();
}
Windowsの場合:
void os::yield() { os::NakedYield(); }
ご覧のとおり、Thread.yeald()
LinuxではすべてのJavaバージョンで同じです。JDK 8の
Windowsを見てみましょうos::NakedYield()
。
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
if (os::Kernel32Dll::SwitchToThreadAvailable()) {
return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep(0);
}
return os::YIELD_UNKNOWN ;
}
Win32 APIのSwitchToThread()
メソッドの存在の追加チェックにおけるJava 9とJava 8の違い。同じコードがJava 6にも存在します。JDK7の
ソースコードos::NakedYield()
は少し異なりますが、動作は同じです。
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
// We use GetProcAddress() as ancient Win9X versions of windows doen't support SwitchToThread.
// In that case we revert to Sleep(0).
static volatile STTSignature stt = (STTSignature) 1 ;
if (stt == ((STTSignature) 1)) {
stt = (STTSignature) ::GetProcAddress (LoadLibrary ("Kernel32.dll"), "SwitchToThread") ;
// It's OK if threads race during initialization as the operation above is idempotent.
}
if (stt != NULL) {
return (*stt)() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep (0) ;
}
return os::YIELD_UNKNOWN ;
}
追加のチェックはSwitchToThread()
、Windows XPおよびWindows Server 2003以降で利用できる方法により削除されました(msdnのメモを参照)。