0、wait()是Object中的方法,其中JDK1.8中,是有重載了三個,不過調用來調用去,最終還是調用了native的wait()方法
wait(long timeout)爲native方法
1、notify()爲Object下的native方法
@HotSpotIntrinsicCandidate
public final native void notify();
2、notifyAll()同樣爲Object下的native方法
@HotSpotIntrinsicCandidate
public final native void notifyAll();
3、有native方法, 就不得不提JNI(Java Native Interface)
這個決定單獨拉一篇文章總結拉
4-0、當一個線程調用某一個對象的wait(),當前的線程就會釋放掉對象鎖,並處於WAITING狀態(長期進入休閒娛樂區),同時也讓出CPU時間片,直到另外一個線程調用同一個對象的notify、或者notifyAll方法,處於休閒娛樂區的當前線程纔會繼續參與對象鎖的競爭
4-1、當一個線程執行某一個對象wait(timeout)方法後,釋放掉持有的對象鎖,會進入TIMED_WATING狀態(限時進入休閒娛樂區),同時讓出CPU時間片,timeout的時間到了後,處於休閒娛樂區的當前線程會繼續參與對象鎖的競爭(別的線程還沒釋放鎖的話,當前線程會處於一直處於BLOCKED狀態)
5-0、假設有多個線程都處於WAITING狀態(多個人都在長期休閒娛樂區),那麼另外一個持有對象鎖的線程再調用notify方法的時候,只會隨機喚醒休閒娛樂區中的一個線程(一個人),可以繼續競爭對象鎖
5-1、假設有多個線程都處於WATING狀態(多個人長期處於休閒娛樂區),那麼一個線程調用notifyAll方法的時候,會通知所有在休閒娛樂區的線程(所有人),繼續參與對象鎖的競爭
5-2、假設有多個線程都處於TIMED_WATING狀態,要麼到timeout時間自動喚醒,要麼等別的線程執行同一個對象的notify或notify喚醒後,繼續參與對象鎖的競爭,牛逼
6、IllegalMonitorStateException: object not locked by thread before wai
IllegalMonitorStateException
終於踩到坑了,爽了,知識掌握不牢固的後果
https://bbs.csdn.net/topics/370105077
7、先回歸一下線程的幾個狀態
a、NEW
b、RUNNABLE(ready和running)
c、BLOCKED
d、WAITING
e、TIMED_WAITING
f、TERMINATED
8、IllegalMonitorStateException,爲啥會拋出這個異常呢
前提:需要線程先獲得一個鎖(對象鎖、類鎖都可以)爲什麼呢?
答:一個對象的wait()方法被當前線程執行時,當前線程會釋放持有的對象鎖,如果當前線程沒有持有對象鎖,那麼你怎麼釋放一個對象鎖呢,所以需要當前線程先獲得一個對象鎖
9、那麼當前線程怎麼獲得對象鎖呢?
答:使用synchronized關鍵字被,獲得對象鎖,類鎖都可以(本身Class也是繼承了Object嘛)
10、一個線程長期處於休閒足療中,也沒人通知,會怎麼樣?
答:徹底放棄CPU時間片,永遠的休閒足療下去……,大bug
總結:
保證多個線程操作的是同一個對象
a、獲取同一個對象的鎖
b、調用同一個對象的wait()或wait(timeout)方法
c、調用同一個對象的notify()、notifyAll()方法
再說一個過程,YY的過程:
a、線程first獲得對象W的鎖
b、線程first調用對象W的wait()方法,線程first讓出CPU時間片,釋放對象鎖,同時自己不參與對象鎖的競爭,進入WAITING狀態(長期休閒足療區)
c、線程second獲得(處於BLOCKED狀態)期盼已久的對象W的鎖,開始處於RUNNABLE狀態,開始執行裏面的業務邏輯,調用對象W的notify()方法,隨機通知休閒足療區的一個線程可以進入BLOCKED狀態,繼續參與對象鎖的競爭,假設就線程first一個人在,那就是喚醒它了
d、線程second的代碼執行完畢,或者同樣執行到wait()方法時會釋放對象鎖,線程first的機會就又來了…………
11、線程與線程之間的交互,真的是超級重要,WAIT、NOTIFY、NOTIFYALL