wait
- wait 是 Object 類的實(shí)例方法菠秒,用于線程間通信
- wait() 方法導(dǎo)致當(dāng)前線程進(jìn)入等待狀態(tài)并釋放對象的鎖秉宿,直到它被通知(其他線程調(diào)用 notify 或 notifyAll 方法戒突。notify / notifyAll 方法解除等待線程的阻塞狀態(tài))
- wait(long timeout) 方法導(dǎo)致當(dāng)前線程釋放對象的鎖,并進(jìn)入等待狀態(tài)直到它被通知或者經(jīng)過指定的時間
- wait() 和 wait(long timeout) 被喚醒后會進(jìn)入阻塞狀態(tài)(Blocked)描睦,直到獲得鎖膊存,才進(jìn)入就緒態(tài)(Runnable)
- wait() 方法只能在同步方法或同步代碼塊中調(diào)用。如果當(dāng)前線程不是對象鎖的持有者,該方法拋出一個 IllegalMonitorStateException 異常
- 可以通過 interrupt() 方法打斷線程的暫停狀態(tài)隔崎,從而使線程立刻拋出 InterruptedException(但不建議使用該方法)今艺,被 interrupt 以后會釋放鎖
- 不需要捕獲異常
sleep
- sleep 是 Thread 類的靜態(tài)方法,作用是阻塞當(dāng)前線程爵卒,讓出 CPU 的使用
- 用于短時間暫停當(dāng)前線程
- sleep(long millis) 使當(dāng)前線程進(jìn)入停滯狀態(tài)虚缎,所以執(zhí)行 sleep() 的線程在指定的時間內(nèi)肯定不會被執(zhí)行
- sleep(long millis) 可能使任意優(yōu)先級的其他線程得到執(zhí)行機(jī)會
- sleep(long millis) 不會釋放鎖
- 調(diào)用 sleep 方法的線程在喚醒之后不保證能獲取到 CPU,它會先進(jìn)入就緒態(tài)(Runnable)钓株,與其他線程競爭 CPU
- 可以通過 interrupt() 方法打斷線程的暫停狀態(tài)实牡,從而使線程立刻拋出 InterruptedException(但不建議使用該方法),被 interrupt 以后會釋放鎖
- 需要捕獲異常
/**
* Thread sleep和wait區(qū)別
*/
public class ThreadTest implements Runnable {
int number = 10;
public void firstMethod() throws Exception {
synchronized (this) {
number += 100;
System.out.println(number);
}
}
public void secondMethod() throws Exception {
synchronized (this) {
/**
* (休息 2s轴合,阻塞線程)
* 以驗(yàn)證當(dāng)前線程對象的機(jī)鎖被占用時创坞,
* 是否被可以訪問其他同步代碼塊
*/
Thread.sleep(2000);
// this.wait(2000);
number *= 200;
}
}
@Override
public void run() {
try {
firstMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest);
thread.start();
threadTest.secondMethod();
}
}
運(yùn)行結(jié)果:
Thread.sleep(2000): 2100
this.wait(2000): 110
yield
- yield 是 Thread 類的靜態(tài)方法,沒有參數(shù)受葛,使當(dāng)前線程從運(yùn)行狀態(tài)變?yōu)榫途w態(tài)
- yield 方法使當(dāng)前線程讓出 CPU题涨,但讓出的時間是不可設(shè)定的
- yield 方法不會釋放鎖
- yield 會把 CPU 讓給相同優(yōu)先級的其他線程,而不會把 CPU 給更高或更低優(yōu)先級的其他線程总滩。若此時沒有其他線程跟它在有一個優(yōu)先級纲堵,則該線程繼續(xù)獲得 CPU 時間,因此可能某線程剛調(diào)用 yield 方法又馬上被執(zhí)行
- 不需要捕獲異常