Udemy Course Multithreading, Concurrency & Performance 14
什麼是Resource?
- 變數(String,Integer…etc)
- Data Structure(Array,Collection,map…)
- File or Connection
- Any Objects
由前一節可知Resource是儲存於Heap,而不是Stack
亦即Resource可以於不同Threads間共享
考量到以下程式
接著建立兩個thread class對其items變數操作
一個是呼叫increment();
另一個則呼叫decrement()
在Main中:
試跑後可以看到:
接著我們嘗試變換一下join的順序:
再次執行得到:
再跑看看
完整程式如下
難道是電腦壞掉了? NO!
理論上預期應該要看到0的
因為同個items變數也都執行完同樣次數的++與--
關鍵點有以下:
- 首先InventoryCounter是shared Object
(其代表兩個thread彼此分享著items member)
2. items++ 與 itmes--
(這兩個運算是同時發生)
(這兩個運算不是atomic operations)
接著就要問-->什麼是Atomic Operations
An Operation or a set operations is considered atomic,if it appears to the rest of the system as if it occurred at once
Single step — all or nothing
No intermediate states
參考其他網站解說,對於全域性資源來說,必須要確保不同thread在同一時間參考的是同一個資源。亦即確保同一時刻只有唯一一個thread對這個資源進行訪問
上面items++並不是atomic operation
其包含了三個步驟:
- 取出目前items的值
- 將目前的值增加1
- 重新儲存該值到items變數
所以上述例子發生的可能計算部分如下
IncrementingThread中可能先從items為0開始做運算
1.IncrementingThread內取出目前值currentVal = 0
2.IncrementingThread內newVal = currentVal + 1 =1
但此時DecrementingThread也開始運算
3.DecrementingThread內取出目前值currentVal = 0
4.DecrementingThread內newVal = currentVal -1 = -1
5.DecrementingThread內Items = newVal = -1
但此時IncrementingThread又搶先
6.IncrementingThread內Items = newVal = +1
最後InventoryCounter內的Items值此時變成"1"而不是預期的0
就算近似的時間參考到items但是不同的排程演算下會得到不同的值
由以上可以理解到共享resource的好處
但是也面臨多threads的挑戰
Case study面對non atomic operation造成非預期的結果