NO IMAGE
1、函式
wait是Object的一個函式,指執行緒處於進入等待狀態,此時執行緒不佔用任何資源,不增加時間限制。wait可以被notify和notifyAll函式喚醒(這兩個也是Object的函式)。
sleep則是Thread的一個函式,指執行緒被呼叫時,佔著CPU不工作.此時,系統的CPU部分資源被佔用,其他執行緒無法進入,會增加時間限制。

所以
sleep(100L)意思為:佔用CPU,執行緒休眠100毫秒

wait(100L)意思為:不佔用CPU,執行緒等待100毫秒
注意:wait和sleep最終都是呼叫native函式。
2、多執行緒
使用多執行緒就沒法繞過同步問題,而wait和sleep對於同步鎖也有不同的效果
(1)在使用上,呼叫obj的wait和notify函式前必須獲取物件鎖,即在synchronized(obj){…}程式碼塊中。
(2)如果都在synchronized程式碼塊中,wait(obj)函式可以釋放鎖,而sleep函式則不釋放鎖。
在wait釋放鎖這裡有一個場景:
有兩個執行緒A和B,在A執行緒中有如下程式碼:
synchronized(mLock){
     …
     mLock.wait();
     …
}
這樣在synchronized處獲取物件鎖,當執行到wait函式時,執行緒A進入等待狀態,並且釋放物件鎖。
在B執行緒中有如下程式碼:
synchronized(mLock){
     …
     mLock.notify();
     …
}
當A的wait函式釋放鎖時,B執行緒的synchronized獲取了物件鎖,開始執行程式碼。
當執行到notify函式時,喚醒A執行緒。但是這時由於B的synchronized程式碼塊未執行完,所以未釋放鎖。所以先執行B執行緒notify後面的程式碼,B的synchronized程式碼執行完後釋放鎖,A執行緒獲取鎖並執行wait之後的程式碼。
(注意,如果有多個wait狀態的obj,notify函式只能喚醒其中一個,是由JVM決定的,而notifyAll可以喚醒所有的)
測試程式碼如下:
Thread a = new Thread(new Runnable() {
@Override
public void run() {
synchronized (mLock){
Log.e("sss", "a 1");
try {
mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("sss", "a 2");
}
}
});
Thread b = new Thread(new Runnable() {
@Override
public void run() {
synchronized (mLock){
Log.e("sss", "b 1");
try {
mLock.notify();
} catch (Exception e) {
e.printStackTrace();
}
Log.e("sss", "b 2");
}
}
});
a.start();
b.start();
列印日誌如下:
12-14 18:50:12.909 22793-22824/com.example.testapplication E/sss: a 1
12-14 18:50:12.909 22793-22825/com.example.testapplication E/sss: b 1
12-14 18:50:12.909 22793-22825/com.example.testapplication E/sss: b 2
12-14 18:50:12.909 22793-22824/com.example.testapplication E/sss: a 2