很久之前的文章了,希望對大家有所幫助。
sleep方法和wait方法異同點是什么?
相同點:
二者都可以讓線程處于凍結狀態(tài)。
不同點:
首先應該明確sleep方法是Thread類中定義的方法,而wait方法是Object類中定義的方法。
- sleep方法必須人為地為其指定時間。
- wait方法既可以指定時間,也可以不指定時間。
- sleep方法時間到,線程處于臨時阻塞狀態(tài)或者運行狀態(tài)。
- wait方法如果沒有被設置時間,就必須要通過notify或者notifyAll來喚醒。
- sleep方法不一定非要定義在同步中。
- wait方法必須定義在同步中。
- 當二者都定義在同步中時:
線程執(zhí)行到sleep,不會釋放鎖。
線程執(zhí)行到wait,會釋放鎖。
針對以上4點,這里舉一個小例子:
synchronized(obj) {
wait();//0 1 2
code....
}
synchronized(obj) {
notifyAll();//3
code....
}
假設此時在wait方法上可能有多個線程例如Thread0、Thread1、Thread2,他們都被存儲到了線程池中,同時將鎖放掉。與此同時,Thread3開始執(zhí)行下方的同步代碼塊,當Thread3執(zhí)行到notifyAll時,0、1、2三個線程都將被喚醒。此時,在同步中就同時存在多個線程,那么此時會引發(fā)多線程的安全問題嗎?
答案是不會的,因為在同步中的線程如果想要執(zhí)行,不但要有執(zhí)行權,還必須要持有鎖,而此時鎖在Thread3手中,所以只有當Thread3執(zhí)行完代碼釋放了鎖后,其他線程才有機會拿到鎖繼續(xù)執(zhí)行。
看到這里我們可以拓展出一個問題:當一個線程進入一個對象的一個synchronized方法后,其他線程是否可以進入此對象的其他方法?
這個問題的答案分為以下幾種情況:
1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。
2.如果這個方法內部調用了wait,則可以進入其他synchronized方法。
3.如果其他的方法都加了synchronized關鍵字,并且內部沒有調用wait,則不能。
4.如果其他方法是static,它用的同步鎖是當前類的字節(jié)碼,與非靜態(tài)的方法不能同步,因為非靜態(tài)的方法用的同步鎖是this。
個人感覺,在學習多線程這部分的知識時,弄清楚何時拿鎖,何時放鎖,是極為重要的。