sleep,yield,wait,join區別

sleep

有兩個重載方法

  • sleep(long millis)  線程睡眠 millis 毫秒
  • sleep(long millis, int nanos)  線程睡眠 millis 毫秒 + nanos 納秒
static void sleep(long millis)
          在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度程序精度和準確性的影響。
static void sleep(long millis, int nanos)
          在指定的毫秒數加指定的納秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度程序精度和準確性的影響。
public static native void sleep(long millis) throws InterruptedException;

public static void sleep(long millis, int nanos)
        throws InterruptedException {
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                "nanosecond timeout value out of range");
    }

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
        millis++;
    }

    sleep(millis);
}

sleep

不會釋放鎖對象

在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度程序精度和準確性的影響。該線程不丟失任何監視器的所屬權。

相當於讓線程睡眠,交出CPU,讓CPU去執行其他的任務。(但是有一點要非常注意,sleep方法不會釋放鎖,也就是說如果當前線程持有對某個對象的鎖,則即使調用sleep方法,其他線程也無法訪問這個對象)。當上面一個線程sleep,它不會釋放鎖,後面的線程都將會被阻塞。當線程睡眠時間滿後,不一定會立即得到執行,因爲此時可能CPU正在執行其他的任務。所以說調用sleep方法相當於讓線程進入阻塞狀態。

sleep(0)

Thread.Sleep(0) 並非是真的要線程掛起0毫秒,意義在於這次調用Thread.Sleep(0)的當前線程確實的被凍結了一下,讓其他線程有機會優先執行。Thread.Sleep(0) 是你的線程暫時放棄cpu,也就是釋放一些未用的時間片給其他線程或進程使用,就相當於一個讓位動作。

yield

暫停當前正在執行的線程對象,並執行其他線程。讓出cpu的執行權使當前線程由運行態到就緒態。它跟sleep方法類似,同樣不會釋放鎖。但是yield不能控制具體的交出CPU的時間,注意,調用yield方法並不會讓線程進入阻塞狀態,而是讓線程重回就緒狀態,它只需要等待重新獲取CPU執行時間,這一點是和sleep方法不一樣的

 public static native void yield();

wait

 void wait()
          在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待。
 void wait(long timeout)
          在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量前,導致當前線程等待。
 void wait(long timeout, int nanos)
          在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量前,導致當前線程等待。

wait會釋放鎖對象。 

public final void wait() throws InterruptedException {
    wait(0);
}
public final void wait(long timeout, int nanos) throws InterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                "nanosecond timeout value out of range");
    }

    if (nanos > 0) {
        timeout++;
    }

    wait(timeout);
}
public final native void wait(long timeout) throws InterruptedException;

join

 void join()
          等待該線程終止。
 void join(long millis)
          等待該線程終止的時間最長爲 millis 毫秒。
 void join(long millis, int nanos)
          等待該線程終止的時間最長爲 millis 毫秒 + nanos 納秒。

 等待該線程終止的時間最長爲 millis 毫秒。超時爲 0 意味着要一直等下去。join方法依賴於最終調用wait方法

假如在main線程中,調用thread.join方法,則main方法會等待thread線程執行完畢或者等待一定的時間。如果調用的是無參join方法,則等待thread執行完畢,如果調用的是指定了時間參數的join方法,則等待一定的時間

public final void join() throws InterruptedException {
    join(0);
}

public final synchronized void join(long millis, int nanos)
        throws InterruptedException {

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                "nanosecond timeout value out of range");
    }

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
        millis++;
    }

    join(millis);
}
public final synchronized void join(long millis)
        throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

 

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