TimeUnit.SECONDS.sleep(10) 看似多此一舉,實為 Thread.sleep 的語義化封裝。本文分析其源碼實現、可讀性優勢與性能影響,給出使用建議。
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns); // 最终仍调用 Thread.sleep
}
}
本質是單位轉換 + 參數校驗 + 委託調用。
// Thread.sleep 需心算單位 Thread.sleep(10); // 10ms Thread.sleep(10 * 1000); // 10s Thread.sleep(10 * 60 * 1000); // 10min // TimeUnit 一目了然 TimeUnit.MILLISECONDS.sleep(10); TimeUnit.SECONDS.sleep(10); TimeUnit.MINUTES.sleep(10);
消除魔術數字,意圖顯式化,維護性大增。
10,000 次調用,Win7 + 4G + JDK7:
TimeUnit.MILLISECONDS.sleep: 100068 ms Thread.sleep: 100134 ms 差異: -66 ms (TimeUnit 略快) 第二輪: TimeUnit: 100222 ms Thread: 100077 ms 差異: +145 ms
差異在統計誤差範圍內,JVM 可能內聯優化消除調用開銷。
TimeUnit 為枚舉類型,天然單例、線程安全、可實現接口、支持 switch,是 Doug Lea 設計智慧的結晶。
忽略微乎其微的性能差異,首選 TimeUnit.sleep 以獲得清晰的時間語義。代碼給人讀,機器執行而已。