Udemy Course Multithreading, Concurrency & Performance 21
通常Multi-Thread程式運行會有互相排隊的狀況就是形成了Deadlock
例如以下兩個Thread進行的邏輯處理:
實際可能的執行順序推敲如下:
Thread2會一直卡在等著鎖A那一步,直到Thread1內把A解鎖
但是Thread1下一步卻是...
此狀況就是形成了
這就好像兩台汽車行駛在十字路口
A由北向南,B由西向東,中間有個交會處可能會有碰撞(形成Dead Lock)
情況如以下程式範例:
嘗試製作兩個物件鎖roadA與roadB,分別先後執行
同樣也寫一個takeRoadB()
接著製作TrainA物件來驅動intersection內的takeRoadA()
同理再做一個TrainB物件來驅動intersection內的takeRoadB()
最後在Main裡面建立單一個Intersection物件
分別注入給後面建立的TrainA與TrainB的Thread物件
並啟動
實際執行會看到:
仔細看看log:
重複跑會看到不同狀況:
像是一開始就撞車:
完整code如下:
以上展示了發生Deadlock的情境
總結如下:
- Mutual Exclusion(互斥):在某時間點,僅單一個Thread可以執行(使用道路)
- Hold & Wait(停止與等待):至少一個Thread持有resource,並等待另一個resource(如上例,RoadA等待RoadB)
- Non-preemptive allocation(非搶佔式分配):resource僅有被該Thread執行完才釋放,而其他Thread只能等待該resource被釋放才能執行
- Circular wait:如上例,某Thread把持著RoadA並等待RoadB被釋放,但是另一個Thread反而把持著RoadB並等待RoadA被釋放
而通常要避免Deadlock的狀況,比較常見的方式就是盡力避免Circular wait
比如前面所說的如下狀況:
原本邏輯如下:
其中改變一下邏輯順序:
回到前面的範例Code,將以下這個地方:
改成:
執行後看到:
所以完整code變成:
結論其他關連技術(找出Deadlock):
- Deadlock detection — Watchdog(偵測沒回應的Thread並停止該Thread)
- Thread interruption(not possible with synchronized)實際就是多Thread的Watchdog
- tryLock operations(not possible with synchronized)另一個Thread在進到會造成lock邏輯前先確認這是否已經被其他Thread 造成lock了
(上面2&3阻止不了synchronized)