1. 程式人生 > >wait,notify,notifyAll,sleep這些方法都跟執行緒的狀態變化有關,為什麼jdk把前三個方法放在Object類裡面,而把sleep放在Thread類裡面?

wait,notify,notifyAll,sleep這些方法都跟執行緒的狀態變化有關,為什麼jdk把前三個方法放在Object類裡面,而把sleep放在Thread類裡面?

首先,雖然這些方法都跟執行緒的狀態變化有關,但wait(),notify(),notifyAll()這三個方法在用法上就跟sleep()方法不太一樣,wait(),notify(),notifyAll()必須在sychronized同步程式碼塊中使用,且要用當前執行緒持有的鎖來呼叫,比如鎖.wait(),鎖.notify(),而sleep()方法則是Thread類的一個靜態方法,直接通過Thread類呼叫即可。

複習一下這幾個方法的作用,wait方法的作用是讓獲得了鎖的執行緒釋放鎖,並且把該執行緒放在這個物件鎖的等待池中,請注意,是當前這個物件鎖,而不是該執行緒擁有的其他物件鎖(一個執行緒可以擁有多個物件鎖

),此時該執行緒狀態會變為waiting;而notify是把該物件鎖的等待池中其中一個執行緒(隨機一個)放到鎖池中,notifyAll則是把該物件鎖的等待池中的執行緒全部放到鎖池中;呼叫seelp方法會把執行緒的狀態變成timed_waiting,但並不會釋放鎖。

知道上面這些後,其實就很容易理解為什麼jdk把wait,notify,notifyAll放在Object類裡面,而把sleep放在Thread類裡面了。我覺得有兩個原因:

1.在java的內建鎖機制中,每個物件都可以成為鎖,也就是說每個物件都可以去呼叫wait,notify方法,而Object類是所有類的一個父類,把這些方法放在Object中,則java中的所有物件都可以去呼叫這些方法了。

2.一個執行緒可以擁有多個物件鎖,wait,notify,notifyAll跟物件鎖之間是有一個繫結關係的,比如你用物件鎖aObject呼叫的wait()方法,那麼你只能通過aObject.notify()或者aObject.notifyAll()來喚醒這個執行緒,這樣jvm很容易就知道應該從哪個物件鎖的等待池中去喚醒執行緒,假如用Thread.wait(),Thread.notify(),Thread.notifyAll()來呼叫,虛擬機器根本就不知道需要操作的物件鎖是哪一個。