線程休眠是 Java 開發經常會用到的一個手段,就是讓目前線程睡一會兒,睡醒之後再繼續運作。
咱大多數程式員,多線程雖然學得不好,但線程休眠,無人不知,無人不曉,也都會用,不就是用 Thread.sleep 方法嘛!而且還将它用到那麼絕,之前不是還有人寫過休眠排序算法和休眠取時間的算法,再來回味下這麼腦洞大開的兩個算法:
休眠排序算法
休眠取時間算法
笑過之後,當然,這不是咋今天要講的主題,棧長今天要講的是如何更優雅的讓線程休眠。
來看下面的休眠程式:
Thread.sleep(87000000);
你知道休眠多久嗎?
醉了……
再把上面的稍微改裝下:
Thread.sleep(24 * 60 * 60 * 1000 + 10 * 60 * 1000);
現在你估計大概能知道休眠多久了,但還是很茫然,很無助,不寫注釋,誰知道休眠多久?機關還是毫秒。。
其實就是休眠 24 小時 10 分鐘,何必整這麼麻煩呢?優雅又簡單的方式來了:
1. TimeUnit.DAYS.sleep(1);
2. TimeUnit.MINUTES.sleep(10);
3.
4. 或者
5.
6. TimeUnit.HOURS.sleep(24);
7. TimeUnit.MINUTES.sleep(10);
使用
java.util.concurrent.TimeUnit
類就可以優雅的搞定,不需要過多的機關運算及修飾,是不是很優雅,很簡單?
上面示範了 HOURS、MINUTES,還有更多的枚舉可以用。
來看下 TimeUnit 的詳細方法和枚舉值:
其實 TimeUnit 還可以用來做時間機關轉換,TimeUnit 提供了各種豐富的時間機關轉換方法。
我們随便來看一個枚舉值:
MINUTES {
public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
public long toMinutes(long d) { return d; }
public long toHours(long d) { return d/(C5/C4); }
public long toDays(long d) { return d/(C6/C4); }
public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
int excessNanos(long d, long m) { return 0; }
}
可以很友善的把分鐘轉換成各種機關的值。
再來看一下 TimeUnit 休眠的原理:
1.
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns);
}
}
其實 TimeUnit 的休眠就是調用了 Thread.sleep 休眠方法,哈哈,隻是把 Thread.sleep 封裝了,這樣,用起來很簡單友善,也提高了可讀性。