使當前執行緒等待,直到它被喚醒,通常是透過被通知或中斷,或直到經過一定的即時時間。
本身屬於一個Object 類,查看原始碼也可知:public class Object {
#查看其原始碼可知,一共有三個重載的方法,詳情原始碼如下:
//第一个重载函数 public final void wait() throws InterruptedException { wait(0L); } //第二个重载函数 public final native void wait(long timeoutMillis) throws InterruptedException; //第三个重载函数 public final void wait(long timeoutMillis, int nanos) throws InterruptedException { if (timeoutMillis < 0) { throw new IllegalArgumentException("timeoutMillis value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) { timeoutMillis++; } wait(timeoutMillis); }
具體實戰呼叫程式碼如下:
如果執行到了wait函數,在這4秒內,會釋放鎖定,並且暫停執行緒。如果這四秒內配合notify()可以喚醒並且得到鎖,如果沒有喚醒,等待其他來競爭。 4秒結束後,會預設自動釋放鎖定
目前執行緒在Thread.wait()等待過程中,如果Thread結束了,是可以自動喚醒的而且自動釋放鎖定
@Override public void run() { synchronized (a) { a.wait(4000); } }
join是Thread類別的方法
查看其原始碼,具體源碼如下,三個重載的方法
//第一个重载函数 public final synchronized void join(final long millis) throws InterruptedException { if (millis > 0) { if (isAlive()) { final long startTime = System.nanoTime(); long delay = millis; do { wait(delay); } while (isAlive() && (delay = millis - TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0); } } else if (millis == 0) { while (isAlive()) { wait(0); } } else { throw new IllegalArgumentException("timeout value is negative"); } } //第二个重载函数 /*等待该线程死亡的时间最多为毫秒加纳秒。 如果两个参数都为0,则意味着永远等待。 这个实现使用了This的循环。 等待电话以this.isAlive为条件。 当一个线程终止this。 调用notifyAll方法。 建议应用程序不要使用wait、notify或notifyAll on Thread实例。 */ 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 > 0 && millis < Long.MAX_VALUE) { millis++; } join(millis); } //第三个重载函数 /*等待线程死亡。 此方法的调用与调用的行为完全相同 InterruptedException—如果任何线程中断了当前线程。 当抛出此异常时,当前线程的中断状态将被清除。 */ public final void join() throws InterruptedException { join(0); }
主要的時間參數邏輯如下:
小於0,拋出例外
等於0,join(A),判斷A是否存在,存在才執行運算。該執行緒執行wait(0)等待,等待A執行緒執行完後才可結束
#大於0,同上,只不過執行的是wait(long millis),等待時間結束後才可繼續執行操作
比較上一個wait函數
/*根据系统计时器和调度器的精度和准确性, 使当前执行的线程在指定的毫秒数内处于睡眠状态(暂时停止执行)。 线程不会失去任何监视器的所有权。*/ 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 > 0 && millis < Long.MAX_VALUE) { millis++; } sleep(millis); }
public static native void yield();
wait | join | |
---|---|---|
Object類別 | Thread類別 | |
執行緒間通訊 | 排序,讓其串列通過 | |
必須要synchronized | #可以不用synchronized |
sleep(long mills):讓出CPU資源,但不會釋放鎖定資源。
看區別,主要是看CPU的運作機制:
它們的差異主要考慮兩點:1.cpu是否繼續執行、2.鎖是否釋放掉。
歸根到底:
wait,notify,notifyall 都是Object物件的方法,是一起使用的,用於鎖定機制,所以會釋放鎖定
而sleep是Thread類,跟鎖沒關係,不會釋放鎖定
但兩者都會讓出cpu資源
以上是Java常用的四個執行緒函數有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!