首先Object中的方法:wait()、notify()、notifyAll()。java
Thread中的方法:start()、run()、sleep()、yield()、interrupt()方法。源碼分析
wait和notify都須要在同步代碼塊中使用。this
java 線程狀態轉換圖:spa
新建一個線程-start()->可運行-run()->運行-->死亡線程
1.若是一個運行的線程sleep(),2.t2.join()方法,3.等待用戶輸入,三種狀況下線程會進入阻塞狀態。對象
運行的線程會試圖獲取鎖,synchronized(),線程獲取到鎖,就進入可運行狀態,若是獲取不到鎖,就進入等待隊列中等待;隊列
若是線程調用wait()方法,JVM會把線程放入等待隊列中,等待被其餘進程喚醒(notify());進程
若是線程調用了對象的 wait()方法,那麼線程便會處於該對象的等待池中,等待池中的線程不會去競爭該對象的鎖。同步
當有線程調用了對象的 notifyAll()方法(喚醒全部 wait 線程)或 notify()方法(只隨機喚醒一個 wait 線程),被喚醒的的線程便會進入該對象的鎖池中,鎖池中的線程會去競爭該對象鎖。源碼
TODO: 結合源碼分析。
總結點:1.sleep與wait的區別:
sleep()不會釋放鎖,wait會釋放鎖,等別的進程調用notify的時候,該阻塞的進程可能會從新得到鎖;
sleep是Thread的方法,wait是Object的方法。sleep不會引發鎖的變化。
join()方法具備使線程排隊運行的做用,當前線程等待。jion(long )中的參數能夠指定等待時間。
join()方法的內部是使用wait實現的,因此join會釋放鎖。
public final synchronized void join(long var1) throws InterruptedException {
long var3 = System.currentTimeMillis();
long var5 = 0L;
if(var1 < 0L) {
throw new IllegalArgumentException("timeout value is negative");
} else {
if(var1 == 0L) {
while(this.isAlive()) {
this.wait(0L);
}
} else {
while(this.isAlive()) {
long var7 = var1 - var5;
if(var7 <= 0L) {
break;
}
this.wait(var7);
var5 = System.currentTimeMillis() - var3;
}
}
}
}