線程的生命周期
所謂的xx生命周期,其實就是某對象的包含產生和銷毀的一張狀態圖。線程的生命周期如下圖所示:
各狀態的說明如下:
-
New新建。新創建的線程經過初始化后,進入Runnable狀態。
-
Runnable就緒。等待線程調度。調度后進入運行狀態。
-
Running運行。
-
Blocked阻塞。暫停運行,解除阻塞后進入Runnable狀態重新等待調度。
-
Dead消亡。線程方法執行完畢返回或者異常終止。
可能有3種情況從Running進入Blocked:
-
同步:線程中獲取同步鎖,但是資源已經被其他線程鎖定時,進入Locked狀態,直到該資源可獲取(獲取的順序由Lock隊列控制)
-
睡眠:線程運行sleep()或join()方法后,線程進入Sleeping狀態。區別在於sleep等待固定的時間,而join是等待子線程執行完。sleep()確保先運行其他線程中的方法。當然join也可以指定一個“超時時間”。從語義上來說,如果兩個線程a,b, 在a中調用b.join(),相當於合並(join)成一個線程。將會使主調線程(即a)堵塞(暫停運行, 不占用CPU資源), 直到被調用線程運行結束或超時, 參數timeout是一個數值類型,表示超時時間,如果未提供該參數,那么主調線程將一直堵塞到被調線程結束。最常見的情況是在主線程中join所有的子線程。
-
等待:線程中執行wait()方法后,線程進入Waiting狀態,等待其他線程的通知(notify)。wait方法釋放內部所占用的瑣,同時線程被掛起,直至接收到通知被喚醒或超時(如果提供了timeout參數的話)。當線程被喚醒並重新占有瑣的時候,程序才會繼續執行下去。
threading.Lock()不允許同一線程多次acquire(), 而RLock允許, 即多次出現acquire和release