JAVA線(xiàn)程sleep()和wait()詳解及實(shí)例
JAVA線(xiàn)程sleep()和wait()詳解及實(shí)例
sleep
1.sleep是Thread的一個(gè)靜態(tài)(static)方法。使得Runnable實(shí)現(xiàn)的線(xiàn)程也可以使用sleep方法。而且避免了線(xiàn)程之前相互調(diào)用sleep()方法,引發(fā)死鎖。
2.sleep()執(zhí)行時(shí)需要賦予一個(gè)沉睡時(shí)間。在沉睡期間(阻塞線(xiàn)程期間),CPU會(huì)放棄這個(gè)線(xiàn)程,執(zhí)行其他任務(wù)。當(dāng)沉睡時(shí)間到了之后,該線(xiàn)程會(huì)自動(dòng)蘇醒,不過(guò)此時(shí)線(xiàn)程不會(huì)立刻被執(zhí)行,而是要等CPU分配資源,和其他線(xiàn)程進(jìn)行競(jìng)爭(zhēng)。
3.此外如果這個(gè)線(xiàn)程之前獲取了一個(gè)機(jī)鎖,在沉睡期間,這個(gè)機(jī)鎖不會(huì)釋放。其他等待這個(gè)機(jī)鎖的程序,必須等待這個(gè)線(xiàn)程醒來(lái),且執(zhí)行完后才能運(yùn)行。
sleep相關(guān)代碼
public class ThreadTest2 { public static void main(String[] args){ System.out.println("begin our test"); ThreadSleep sleep = new ThreadSleep(); try { Thread thread1 = new Thread(sleep,"路人甲"); Thread thread2 = new Thread(sleep,"路人乙"); thread1.start(); thread2.start(); }catch(Exception e){ e.printStackTrace(); } System.out.println("test is over"); } } class ThreadSleep implements Runnable{ int count = 0; @Override public void run(){ System.out.println(Thread.currentThread().getName() + " say : hello sleep !!"); count(); } public void count(){ while(count < 20) { System.out.println(Thread.currentThread().getName() + " say : count is " + count); try { count++; Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } } } }
輸出日志
begin our test test is over 路人甲 say : hello sleep !! 路人甲 say : count is 0 路人乙 say : hello sleep !! 路人乙 say : count is 1 路人甲 say : count is 2 路人乙 say : count is 2 路人甲 say : count is 4 路人乙 say : count is 4 路人甲 say : count is 6 路人乙 say : count is 7 路人乙 say : count is 8 路人甲 say : count is 8 路人甲 say : count is 10 路人乙 say : count is 10 路人乙 say : count is 12 路人甲 say : count is 12 路人乙 say : count is 14 路人甲 say : count is 14 路人甲 say : count is 16 路人乙 say : count is 16 路人甲 say : count is 18 路人乙 say : count is 18
通過(guò)日志可以發(fā)現(xiàn)線(xiàn)程甲和線(xiàn)程乙基本是交替執(zhí)行,但是并不規(guī)律,且出現(xiàn)了并發(fā)問(wèn)題。
該情況是由于代碼中設(shè)置了睡眠時(shí)間為100毫秒,由于count遞增執(zhí)行速度很快,所以線(xiàn)程差不多是同時(shí)睡眠,然后同時(shí)蘇醒并導(dǎo)致了并發(fā)的出現(xiàn)。
接下來(lái)要添加synchronize塊,檢查sleep時(shí)機(jī)鎖是否釋放
public class ThreadTest2 { public static void main(String[] args){ System.out.println("begin our test"); ThreadSleep sleep = new ThreadSleep(); try { Thread thread1 = new Thread(sleep,"路人甲"); Thread thread2 = new Thread(sleep,"路人乙"); thread1.start(); thread2.start(); }catch(Exception e){ e.printStackTrace(); } System.out.println("test is over"); } } class ThreadSleep implements Runnable{ int count = 0; @Override public void run(){ System.out.println(Thread.currentThread().getName() + " say : hello sleep !!"); count(); } public void count(){ while(count < 20) { synchronized (this) { System.out.println(Thread.currentThread().getName() + " say : count is " + count); try { count++; Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } } } } }
輸出日志
begin our test 路人甲 say : hello sleep !! 路人甲 say : count is 0 test is over 路人乙 say : hello sleep !! 路人甲 say : count is 1 路人甲 say : count is 2 路人甲 say : count is 3 路人甲 say : count is 4 路人甲 say : count is 5 路人甲 say : count is 6 路人甲 say : count is 7 路人甲 say : count is 8 路人甲 say : count is 9 路人甲 say : count is 10 路人甲 say : count is 11 路人甲 say : count is 12 路人甲 say : count is 13 路人甲 say : count is 14 路人甲 say : count is 15 路人甲 say : count is 16 路人甲 say : count is 17 路人甲 say : count is 18 路人甲 say : count is 19 路人乙 say : count is 20
通過(guò)日志可以看出,基本是線(xiàn)程甲在執(zhí)行,這是因?yàn)閟leep時(shí),機(jī)鎖一直在線(xiàn)程甲上,所以線(xiàn)程乙只能一直等待直到線(xiàn)程甲釋放鎖。
wait
1.wait()是Object類(lèi)的一個(gè)方法。當(dāng)調(diào)用wait()方法時(shí),該線(xiàn)程會(huì)進(jìn)入和該對(duì)象相關(guān)的等待池中,并釋放它所擁有的機(jī)鎖。
2.執(zhí)行wait()后,必須使用notify()方法或notifyAll()方法或設(shè)置等待時(shí)間(wait(long time))喚醒在等待線(xiàn)程池中的線(xiàn)程。
3.wait()必須放在synchronized block中,否則會(huì)在運(yùn)行時(shí)報(bào)“java.lang.IllegalMonitorStateException”異常
wait相關(guān)代碼
public class ThreadTest2 { public static void main(String[] args) { System.out.println("begin our test"); ThreadSleep sleep = new ThreadSleep(); try { Thread thread1 = new Thread(sleep, "路人甲"); Thread thread2 = new Thread(sleep, "路人乙"); thread1.start(); thread2.start(); } catch (Exception e) { e.printStackTrace(); } System.out.println("test is over"); } } class ThreadSleep implements Runnable { int count = 0; @Override public void run() { System.out.println(Thread.currentThread().getName() + " say : hello sleep !!"); count(); } public void count() { while (count < 20) { synchronized (this) { System.out.println(Thread.currentThread().getName() + " say : count is " + count); try { count++; this.wait(100); } catch (Exception e) { e.printStackTrace(); } } } } }
輸出日志
begin our test 路人甲 say : hello sleep !! 路人甲 say : count is 0 test is over 路人乙 say : hello sleep !! 路人乙 say : count is 1 路人甲 say : count is 2 路人乙 say : count is 3 路人甲 say : count is 4 路人乙 say : count is 5 路人甲 say : count is 6 路人乙 say : count is 7 路人甲 say : count is 8 路人乙 say : count is 9 路人甲 say : count is 10 路人乙 say : count is 11 路人甲 say : count is 12 路人乙 say : count is 13 路人乙 say : count is 14 路人甲 say : count is 15 路人乙 say : count is 16 路人甲 say : count is 17 路人乙 say : count is 18 路人甲 say : count is 19
通過(guò)日志可以發(fā)現(xiàn)在wait的情況下,機(jī)鎖會(huì)被釋放。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- java中sleep方法和wait方法的五個(gè)區(qū)別
- Java線(xiàn)程中sleep和wait的區(qū)別詳細(xì)介紹
- Java中sleep()與wait()的區(qū)別總結(jié)
- 詳解Java中wait和sleep的區(qū)別
- Java線(xiàn)程阻塞方法sleep()與wait()的全面講解
- 詳解Java中的sleep()和wait()的區(qū)別
- Java中wait與sleep的區(qū)別講解(wait有參及無(wú)參區(qū)別)
- java 中sleep() 和 wait() 的對(duì)比
- java sleep()和wait()的區(qū)別點(diǎn)總結(jié)
- Java面試題篇之Sleep()方法與Wait()方法的區(qū)別詳解
相關(guān)文章
Java實(shí)現(xiàn)的時(shí)間戳與date對(duì)象相互轉(zhuǎn)換功能示例
這篇文章主要介紹了Java實(shí)現(xiàn)的時(shí)間戳與date對(duì)象相互轉(zhuǎn)換功能,結(jié)合具體實(shí)例形式分析了java日期與時(shí)間戳類(lèi)型的表示與轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2017-06-06spring?boot只需兩步優(yōu)雅整合activiti示例解析
這篇文章主要主要來(lái)教大家spring?boot優(yōu)雅整合activiti只需兩步就可完成測(cè)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步2022-03-03Spring Boot2.x集成JPA快速開(kāi)發(fā)的示例代碼
這篇文章主要介紹了Spring Boot2.x集成JPA快速開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05解析Java中PriorityQueue優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的源碼及用法
優(yōu)先級(jí)隊(duì)列是一種隊(duì)列結(jié)構(gòu),是0個(gè)或多個(gè)元素的集合,每個(gè)元素都有一個(gè)優(yōu)先權(quán),PriorityQueue被內(nèi)置于JDK中,本文就來(lái)解析Java中PriorityQueue優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的源碼及用法.2016-05-05SpringMVC深入講解文件的上傳下載實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了springMVC實(shí)現(xiàn)文件上傳和下載的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06springboot快速整合Mybatis組件的方法(推薦)
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。這篇文章主要介紹了springboot快速整合Mybatis組件的方法,需要的朋友可以參考下2019-11-11SpringBoot整合SpringSecurity認(rèn)證與授權(quán)
在項(xiàng)目開(kāi)發(fā)中,權(quán)限認(rèn)證是很重要的,尤其是一些管理類(lèi)的系統(tǒng),對(duì)于權(quán)限要求更為嚴(yán)格,本文主要介紹了SpringBoot整合SpringSecurity認(rèn)證與授權(quán),感興趣的可以了解一下2023-11-11