-Object類中有五個(gè)關(guān)于線程的方法:三個(gè)重載的wait()方法和notify()、notifyAll()
問(wèn)題1:為什么這些方法不定義在Thread類里面作為靜態(tài)方法使用?而是在Object類里面?
這個(gè)問(wèn)題先放下,先看線程狀態(tài)圖:
new出一個(gè)線程后,處于Runnable狀態(tài),獲得CPU控制權(quán)后執(zhí)行,接著處于Running狀態(tài),如果沒(méi)有控制,正常執(zhí)行完畢會(huì)自動(dòng)消亡即Dead。
處于Running狀態(tài)的線程,第一:調(diào)用sleep或者join方法或者阻塞IO會(huì)進(jìn)入阻塞狀態(tài),一旦釋放會(huì)自動(dòng)進(jìn)入Runnable狀態(tài)。第二:調(diào)用wait方法會(huì)使線程處于等待池(是個(gè)對(duì)象池),一旦調(diào)用notify()或者interupt()方法線程會(huì)進(jìn)入鎖池(是個(gè)對(duì)象池),然后就會(huì)進(jìn)入Runnable狀態(tài),等待CPU控制權(quán)。第三:運(yùn)行中的線程進(jìn)入synchronized方法或者synchronized代碼段,會(huì)進(jìn)入鎖池,并且只有在synchronized里面才能調(diào)用wait()方法。

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41


2

3

4

5

6

7

8

9

10

11

12

13

try{
Thread.sleep(200)
}catch(Exception e)
{}
14

15

16














try{
Thread.sleep(200)
}catch(Exception e)
{}





當(dāng)調(diào)用push方法的時(shí)候,當(dāng)前線程鎖定this對(duì)象,當(dāng)棧滿了,開(kāi)始調(diào)用wait()方法,使生產(chǎn)者線程處于等待池。當(dāng)消費(fèi)者線程通知生產(chǎn)者線程繼續(xù)生產(chǎn)的時(shí)候,wait()方法終結(jié),如果使用if條件,并且處于多線程狀態(tài)(有若干個(gè)生產(chǎn)者線程),那么這個(gè)時(shí)候有可能另外一個(gè)處于鎖池狀態(tài)的線程開(kāi)始執(zhí)行,那么該線程會(huì)生產(chǎn)導(dǎo)致棧滿,而這個(gè)時(shí)候剛執(zhí)行完wait()方法的線程也開(kāi)始生產(chǎn),那么會(huì)導(dǎo)致溢出。所以采用while循環(huán),繼續(xù)判斷棧是否滿,如果不滿,那么執(zhí)行生產(chǎn),這個(gè)時(shí)候絕對(duì)不會(huì)出現(xiàn)任何問(wèn)題,因?yàn)閟ynchronized該線程獲得鎖,其余線程無(wú)法進(jìn)入,必定安全。
釋放對(duì)象的鎖:
1、執(zhí)行完同步代碼塊,就會(huì)釋放鎖
2、執(zhí)行同步代碼塊的過(guò)程中,執(zhí)行了鎖所屬對(duì)象的wait()方法,這個(gè)線程會(huì)釋放鎖,進(jìn)入對(duì)象的等待池。
3、執(zhí)行同步代碼塊的過(guò)程中,遇到異常而導(dǎo)致線程終止,鎖也會(huì)釋放
不會(huì)釋放鎖:
1、執(zhí)行了Thread.sleep()方法,當(dāng)前線程放棄CPU,開(kāi)始睡眠,但不會(huì)釋放鎖。
2、執(zhí)行同步代碼塊的過(guò)程中,執(zhí)行了Thread.yield()方法,當(dāng)前線程放棄CPU但不會(huì)釋放鎖。