淺談sleep方法和wait方法的異同
在我學到多執行緒技術這裡時,感到sleep方法和wait方法二者給我造成了一些困惑,所以我在此將二者小小地總結
一下,希望對大家有所幫助。
sleep方法和wait方法異同點是什麼?
相同點:
二者都可以讓執行緒處於凍結狀態。不同點:
首先應該明確sleep方法是Thread類中定義的方法,而wait方法是Object類中定義的方法。1,sleep方法必須人為地為其指定時間。
wait方法既可以指定時間,也可以不指定時間。
2,sleep方法時間到,執行緒處於臨時阻塞狀態或者執行狀態。wait方法如果沒有被設定時間,就必須要通過notify或者notifyAll來喚醒。
3,sleep方法不一定非要定義在同步中。
wait方法必須定義在同步中。
4,當二者都定義在同步中時,
執行緒執行到sleep,不會釋放鎖。
執行緒執行到wait,會釋放鎖。針對以上4點,這裡舉一個小例子:
- synchronized(obj)
- {
- wait();//0 1 2
- code....
- }
- synchronized(obj)
- {
- notifyAll();//3
- code....
-
}
假設此時在wait方法上可能有多個執行緒例如Thread0、Thread1、Thread2,他們都被儲存到了執行緒池中,同時將
鎖放掉。與此同時,Thread3開始執行下方的同步程式碼塊,當Thread3執行到notifyAll時,0、1、2三個執行緒都將被喚
醒。此時,在同步中就同時存在多個執行緒,那麼此時會引發多執行緒的安全問題嗎?
答案是不會的,因為在同步中的執行緒如果想要執行,不但要有執行權,還必須要持有鎖,而此時鎖在Thread3手
中,所以只有當Thread3執行完程式碼釋放了鎖後,其他執行緒才有機會拿到鎖繼續執行。
看到這裡我們可以拓展出一個問題:當一個執行緒進入一個物件的一個synchronized方法後,其他執行緒是否可
以進入此物件的其他方法?
這個問題的答案分為以下幾種情況:
1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。
2.如果這個方法內部呼叫了wait,則可以進入其他synchronized方法。
3.如果其他的方法都加了synchronized關鍵字,並且內部沒有呼叫wait,則不能。4.如果其他方法是static,它用的同步鎖是當前類的位元組碼,與非靜態的方法不能同步,因為非靜態的方法用的同
步鎖是this。
個人感覺,在學習多執行緒這部分的知識時,弄清楚何時拿鎖,何時放鎖,是極為重要的。