您好,登錄后才能下訂單哦!
JAVA線程sleep()和wait()詳解及實(shí)例
sleep
1.sleep是Thread的一個(gè)靜態(tài)(static)方法。使得Runnable實(shí)現(xiàn)的線程也可以使用sleep方法。而且避免了線程之前相互調(diào)用sleep()方法,引發(fā)死鎖。
2.sleep()執(zhí)行時(shí)需要賦予一個(gè)沉睡時(shí)間。在沉睡期間(阻塞線程期間),CPU會(huì)放棄這個(gè)線程,執(zhí)行其他任務(wù)。當(dāng)沉睡時(shí)間到了之后,該線程會(huì)自動(dòng)蘇醒,不過此時(shí)線程不會(huì)立刻被執(zhí)行,而是要等CPU分配資源,和其他線程進(jìn)行競(jìng)爭(zhēng)。
3.此外如果這個(gè)線程之前獲取了一個(gè)機(jī)鎖,在沉睡期間,這個(gè)機(jī)鎖不會(huì)釋放。其他等待這個(gè)機(jī)鎖的程序,必須等待這個(gè)線程醒來,且執(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
通過日志可以發(fā)現(xiàn)線程甲和線程乙基本是交替執(zhí)行,但是并不規(guī)律,且出現(xiàn)了并發(fā)問題。
該情況是由于代碼中設(shè)置了睡眠時(shí)間為100毫秒,由于count遞增執(zhí)行速度很快,所以線程差不多是同時(shí)睡眠,然后同時(shí)蘇醒并導(dǎo)致了并發(fā)的出現(xiàn)。
接下來要添加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
通過日志可以看出,基本是線程甲在執(zhí)行,這是因?yàn)閟leep時(shí),機(jī)鎖一直在線程甲上,所以線程乙只能一直等待直到線程甲釋放鎖。
wait
1.wait()是Object類的一個(gè)方法。當(dāng)調(diào)用wait()方法時(shí),該線程會(huì)進(jìn)入和該對(duì)象相關(guān)的等待池中,并釋放它所擁有的機(jī)鎖。
2.執(zhí)行wait()后,必須使用notify()方法或notifyAll()方法或設(shè)置等待時(shí)間(wait(long time))喚醒在等待線程池中的線程。
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
通過日志可以發(fā)現(xiàn)在wait的情況下,機(jī)鎖會(huì)被釋放。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。