Java的Object.wait(long)在等待時間過去后會繼續往后執行嗎
Object.wait(long)方法相比於wait,多了個等待時長,那么當等待時長過去后,線程會繼續往下執行嗎?
- 單個線程執行
- 多個線程並發執行
public class ThreadWaitDemo {
public static final int WAIT_IN_SECONDS = 2;
public static final int NOTIFY_IN_SECONDS = 6;
public static void main(String[] args) throws InterruptedException {
ThreadWaitDemo threadWait = new ThreadWaitDemo();
Thread a = new Thread(threadWait::justWaitAndPrint, "t1");
Thread b = new Thread(threadWait::justNotify, "t2");
a.start();
// ① 先注釋這段,讓t1自己執行
b.start();
}
public synchronized void justWaitAndPrint() {
try {
System.out.println(Thread.currentThread().getName() + ": I am in");
System.out.println(Thread.currentThread().getName() + ": I am gonna wait");
long start = System.currentTimeMillis();
wait(WAIT_IN_SECONDS * 1000);
// 如果時間過了就可以解除等待狀態的話,那么這里的時間間隔就會接近2s
System.out.println("wait end " + (System.currentTimeMillis() - start) / 1000.0 + "seconds");
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + ": Oops, something bad happen " + e);
}
System.out.println(Thread.currentThread().getName() + ": I am out");
}
public synchronized void justNotify() {
try {
TimeUnit.SECONDS.sleep(NOTIFY_IN_SECONDS);
System.out.println(Thread.currentThread().getName() + ": I am in");
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + ": Oops, something bad happen " + e);
}
System.out.println(Thread.currentThread().getName() + ": I am out");
}
}
-
第一種情況下,運行結果
t1: I am in
t1: I am gonna wait
wait end 2.004seconds
t1: I am out -
第二種情況下,運行結果
t1: I am in
t1: I am gonna wait
t2: I am in
t2: I am out
wait end 6.002seconds // 等待時間會隨NOTIFY_IN_SECONDS變化
t1: I am out
結論:wait(long)在無鎖競爭情況下,在等待時間過去后就直接重新獲取鎖,往后執行;但是在競爭條件下,都會等獲取到鎖了才可以往下執行
附:Java線程狀態
Java的Thread類中定義了一個線程狀態的枚舉,State
public enum State {
/**
* 線程還未啟動
*/
NEW,
/**
* Runnable的線程已經在JVM中執行了,但是可能還在等待OS的一些資源例如處理器
*/
RUNNABLE,
/**
* 線程處於等待一個monitor鎖的狀態
* 1.等待進入synchronized塊或方法
* 2.在調用Object.wait后重新進入同步塊
*/
BLOCKED,
/**
* 假設線程A進入waiting狀態,事實上是等待其他的線程B去執行某個特殊的操作
* 可以讓線程進入waiting狀態的幾種情況:
* 1.Object#wait() 等待線程B調用Object.notify()或者Object.notifyAll()
* 2.B.join() 等待線程B結束
* 3.LockSupport.park() 等待線程B調用LockSupport.unpark(A);
*/
WAITING,
/**
* 有時間約束的線程等待狀態
* 1. Thread.sleep}
* 2. Object.wait(long)
* 3. Thread.join(long)
* 4. LockSupport.parkNanos
* 5. LockSupport.parkUntil(long deadline)
*/
TIMED_WAITING,
/**
* 終止狀態,線程執行完畢
*/
TERMINATED;
}