Java中wait與sleep的區(qū)別講解(wait有參及無參區(qū)別)
1. wait() 與wait( long timeout ) 區(qū)別
public class WaitDemo4 {
public static void main(String[] args) {
Object lock = new Object();
Object lock2 = new Object();
new Thread(() -> {
System.out.println("線程1: 開始執(zhí)行" + LocalDateTime.now());
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程1: 執(zhí)行完成" + LocalDateTime.now());
}
},"無參wait線程").start();
new Thread(() -> {
System.out.println("線程2: 開始執(zhí)行" + LocalDateTime.now());
synchronized (lock2) {
try {
lock2.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程2: 執(zhí)行完成" + LocalDateTime.now());
}
},"有參wait線程").start();
}
}
輸出:
線程2: 開始執(zhí)行2022-04-12T12:13:57.130
線程1: 開始執(zhí)行2022-04-12T12:13:57.130
線程2: 執(zhí)行完成2022-04-12T12:13:58.130不同點(diǎn):
1.wait( long timeout) :當(dāng)線程超過了設(shè)置時(shí)間之后,自動(dòng)恢復(fù)執(zhí)行;而wait() 無線等待狀態(tài)。

2. 使用無參的wait方法,線程會(huì)進(jìn)入WAITING; 使用有參的wait方法,線程會(huì)進(jìn)入TIMED_WAITING。


public class WaitDemo5 {
public static void main(String[] args) {
Object lock = new Object();
Object lock2 = new Object();
new Thread(() -> {
synchronized (lock2) {
System.out.println("線程2: 開始執(zhí)行" + LocalDateTime.now());
try {
lock2.wait(60 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程2: 執(zhí)行完成" + LocalDateTime.now());
}
},"有參wait線程").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("喚醒線程2");
lock2.notify();
}
}).start();
}
}
輸出:
線程2: 開始執(zhí)行2022-04-12T12:28:23.200
喚醒線程2
線程2: 執(zhí)行完成2022-04-12T12:28:24.169public class WaitDemo6 {
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
System.out.println("線程1: 開始執(zhí)行" + LocalDateTime.now());
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程1: 執(zhí)行完成" + LocalDateTime.now());
}
},"無參wait線程").start();
new Thread(() -> {
System.out.println("線程2: 開始執(zhí)行" + LocalDateTime.now());
synchronized (lock) {
try {
lock.wait(60 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程2: 執(zhí)行完成" + LocalDateTime.now());
}
},"有參wait線程").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println("喚醒所有線程");
lock.notifyAll();
}
}).start();
}
}
輸出:
線程1: 開始執(zhí)行2022-04-12T12:34:34.317
線程2: 開始執(zhí)行2022-04-12T12:34:34.317
喚醒所有線程
線程2: 執(zhí)行完成2022-04-12T12:34:35.295
線程1: 執(zhí)行完成2022-04-12T12:34:35.295共同點(diǎn):
1. 無論是有參的wait方法還是無參的wait方法,它都可以使用當(dāng)前線程進(jìn)入休眠狀態(tài)。
2.無論是有參的wait方法還是無參的wait方法,它都可以使用notify / ontifyAll進(jìn)行喚醒。
2. wait(0) 與 sleep(0)區(qū)別
public class WaitSleepDemo7 {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("線程1:開始執(zhí)行");
try {
lock.wait(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程1:執(zhí)行結(jié)束");
}
},"wait(0)");
t1.start();
Thread t2 = new Thread(() -> {
System.out.println("線程2:開始執(zhí)行");
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程2:執(zhí)行結(jié)束");
}, "sleep(0)");
t2.start();
}
}
輸出:
線程1:開始執(zhí)行
線程2:開始執(zhí)行
線程2:執(zhí)行結(jié)束wait (0) : 無限期等待下去,相當(dāng)于wait();
sleep(0) :相當(dāng)于Thread.yeild() , 讓出CPU執(zhí)行權(quán),重新調(diào)度,但是sleep(0) 會(huì)繼續(xù)執(zhí)行。
3. wait 和sleep 釋放代碼
wait 和 sleep 在有所的情況下的鎖處理行為是完全不同的:
public class WaitSleepDemo8 {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Object lock2 = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("線程1:開始執(zhí)行");
try {
lock.wait(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程1:結(jié)束執(zhí)行");
}
}, "wait");
t1.start();
Thread t2 = new Thread(() -> {
synchronized (lock2) {
System.out.println("線程2:開始執(zhí)行");
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程2:結(jié)束執(zhí)行");
}
}, "sleep");
t2.start();
// 創(chuàng)建 2 個(gè)線程,先讓線程休眠 1s 之后,嘗試獲取,看能不能獲取到鎖
// 如果可以獲取到鎖,說明休眠時(shí)線程是釋放鎖的,而如果獲取不到鎖,說明是不釋放鎖
Thread t3 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("嘗試獲取 wait 方法的鎖");
synchronized (lock) {
System.out.println("成功獲取 wait 的鎖");
}
}, "wait2");
t3.start();
Thread t4 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("嘗試獲取 sleep 方法的鎖");
synchronized (lock2) {
System.out.println("成功獲取 sleep 的鎖");
}
}, "sleep2");
t4.start();
}
}
輸出:
線程1:開始執(zhí)行
線程2:開始執(zhí)行
嘗試獲取 sleep 方法的鎖
嘗試獲取 wait 方法的鎖
成功獲取 wait 的鎖
線程1:結(jié)束執(zhí)行
線程2:結(jié)束執(zhí)行
成功獲取 sleep 的鎖wait方法(不管是有參還是無參)在執(zhí)行的時(shí)候都會(huì)釋放鎖;而sleep 方法不會(huì)釋放鎖。
4. wait 與 sleep 區(qū)別
相同點(diǎn):
1. 都是可以讓線程進(jìn)入休眠
2. 都可以響應(yīng)Interrupt(中斷)請(qǐng)求
不同點(diǎn):
1. wait必須配合synchronized一起使用;而sleep不需要。
2. wait 屬于Object(對(duì)象)的方法;而sleep屬于Thread(線程)的方法。
3. sleep 不釋放鎖;而wait釋放鎖。
4. sleep 必須要傳遞一個(gè)數(shù)值類型的參數(shù);而wait可以不傳參。
5. sleep 讓線程進(jìn)入到TIMED_WAITING狀態(tài);而無參的wait方法讓線程進(jìn)入了WAITING狀態(tài)。
6. 一般情況下,sleep只能等待超時(shí)時(shí)間之后再回復(fù)執(zhí)行;而wait可以接受notify / notifiAll之后就緒執(zhí)行。
(MS):
1.為什么 wait 釋放鎖? sleep 不釋放鎖?
【JVM 強(qiáng)制語法檢查,wait ?法默認(rèn)等待?期限】
2.為什么 wait 要放在 Object 中?
【wait 使?要加鎖,也就是要操作鎖,鎖是針對(duì)對(duì)象級(jí)別的??線程級(jí)別的,線程和對(duì)象是?對(duì)多,所以 wait 最便利的?式是放在 Object 中】
到此這篇關(guān)于Java中wait與sleep的區(qū)別講解(wait有參及無參區(qū)別)的文章就介紹到這了,更多相關(guān)java wait與sleep內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中sleep方法和wait方法的五個(gè)區(qū)別
- Java線程中sleep和wait的區(qū)別詳細(xì)介紹
- Java中sleep()與wait()的區(qū)別總結(jié)
- Java面試題篇之Sleep()方法與Wait()方法的區(qū)別詳解
- 詳解Java中wait和sleep的區(qū)別
- 詳解Java中的sleep()和wait()的區(qū)別
- java sleep()和wait()的區(qū)別點(diǎn)總結(jié)
- Java詳細(xì)分析sleep和wait方法有哪些區(qū)別
- java面試突擊之sleep和wait有什么區(qū)別詳析
- Java中wait()與sleep()兩者的不同深入解析
相關(guān)文章
SpringBoot3配置Logback日志滾動(dòng)文件的方法
本文介紹了在SpringBoot3中配置Logback日志滾動(dòng)文件的方法,因?yàn)镾pringBoot3內(nèi)置的logback版本是1.4.14,之前使用SpringBoot2.1.5的logback配置發(fā)現(xiàn)有些東西不能生效了,需要的朋友可以參考下2024-08-08
SpringCloud+SpringBoot項(xiàng)目搭建結(jié)構(gòu)層次的實(shí)例
這篇文章詳細(xì)介紹了SpringCloud項(xiàng)目的架構(gòu)層次及其搭建經(jīng)驗(yàn),包括Controller層、Service層、Repository層、Entity層、DTO層、Exception層等,通過文字和圖片的形式,幫助讀者理解如何組織和實(shí)現(xiàn)一個(gè)SpringBoot項(xiàng)目的不同層次2025-01-01
java注解之運(yùn)行時(shí)修改字段的注解值操作
這篇文章主要介紹了java注解之運(yùn)行時(shí)修改字段的注解值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Java使用TCP套接字實(shí)現(xiàn)多人聊天功能詳解
這篇文章主要介紹了Java使用TCP套接字實(shí)現(xiàn)多人聊天功能,結(jié)合實(shí)例形式詳細(xì)分析了java使用socket通信實(shí)現(xiàn)tcp協(xié)議下的聊天功能客戶端與服務(wù)器端相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-10-10
java字節(jié)碼框架ASM的深入學(xué)習(xí)
這篇文章主要給大家介紹了java中字節(jié)碼框架ASM的相關(guān)資料,文中介紹的非常詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。2017-01-01
Java Mybatis框架增刪查改與核心配置詳解流程與用法
MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲(chǔ)過程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO為數(shù)據(jù)庫中的記錄2021-10-10

