基本的差別
- sleep是Thread類的方法,wait是Object類中定義的方法
- sleep()方法可以在任何地方使用
- wait()方法只能在synchronized方法或者synchronized塊中使用
本質區別
- Thread.sleep()只會讓出CPU資源,不會導致鎖行爲的改變
- Object.wait()不僅讓出CPU資源,還會釋放已經佔有的同步鎖
我們來看下面兩個例子
package com.mtli.thread;
/**
* @Description:
* @Author: Mt.Li
* @Create: 2020-05-05 07:56
*/
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程A正在等待獲取同步鎖");
try {
synchronized (lock) {
System.out.println("線程A已經獲取到鎖");
Thread.sleep(20);
System.out.println("線程A執行wait方法");
lock.wait(1000);
System.out.println("線程A執行完畢");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程B正在等待獲取同步鎖");
try {
synchronized (lock) {
System.out.println("線程B已經獲取到鎖");
Thread.sleep(10);
System.out.println("線程B執行sleep方法");
Thread.sleep(1000);
System.out.println("線程B執行完畢");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
// 執行結果:
線程A正在等待獲取同步鎖
線程A已經獲取到鎖
線程B正在等待獲取同步鎖
線程A執行wait方法
線程B已經獲取到鎖
線程B執行sleep方法
線程B執行完畢
線程A執行完畢
從結果我們可以分析,線程A執行wait()方法之前,線程B只是啓動運行並在鎖池中進行等待,線程A執行wait()方法之後,線程B需要獲取鎖才能執行的部分被執行了,說明這個時候,線程B獲取到了lock對象鎖,也就驗證了wait不僅僅釋放CPU資源,還會釋放同步鎖,這時候該線程就會進入當前對象的等待池中,等待時間結束,或者被主動喚醒。
對代碼稍加修改:
package com.mtli.thread;
/**
* @Description:
* @Author: Mt.Li
* @Create: 2020-05-05 07:56
*/
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程A正在等待獲取同步鎖");
try {
synchronized (lock) {
System.out.println("線程A已經獲取到鎖");
Thread.sleep(20);
System.out.println("線程A執行sleep方法");
Thread.sleep(1000);
System.out.println("線程A執行完畢");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("線程B正在等待獲取同步鎖");
try {
synchronized (lock) {
System.out.println("線程B已經獲取到鎖");
Thread.sleep(10);
System.out.println("線程B執行sleep方法");
Thread.sleep(1000);
System.out.println("線程B執行完畢");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
// 結果:
線程A正在等待獲取同步鎖
線程A已經獲取到鎖
線程B正在等待獲取同步鎖
線程A執行sleep方法
線程A執行完畢
線程B已經獲取到鎖
線程B執行sleep方法
線程B執行完畢
從結果可以顯而易見,sleep方法並不會釋放鎖,但是會釋放CPU資源(出讓CPU時間片,畢竟Java線程是搶佔式的)
以上均爲個人理解,若有錯誤,請各位看官及時提出(輕噴),如有爭議,大家可以一起交流