天天看點

線程休眠隻會用 Thread.sleep?來,教你新姿勢!

線程休眠隻會用 Thread.sleep?來,教你新姿勢!

線程休眠是 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 的詳細方法和枚舉值:

線程休眠隻會用 Thread.sleep?來,教你新姿勢!

其實 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 封裝了,這樣,用起來很簡單友善,也提高了可讀性。