Udemy Course Multithreading, Concurrency & Performance 14

Resource Sharing

ZONGRU Li
Jul 26, 2021

什麼是Resource?

  1. 變數(String,Integer…etc)
  2. Data Structure(Array,Collection,map…)
  3. File or Connection
  4. Any Objects

由前一節可知Resource是儲存於Heap,而不是Stack

亦即Resource可以於不同Threads間共享

考量到以下程式

接著建立兩個thread class對其items變數操作

一個是呼叫increment();

另一個則呼叫decrement()

在Main中:

join()會真的結束才離開join(),詳前面第6節

試跑後可以看到:

接著我們嘗試變換一下join的順序:

再次執行得到:

再跑看看

完整程式如下

難道是電腦壞掉了? NO!

理論上預期應該要看到0的

因為同個items變數也都執行完同樣次數的++與--

關鍵點有以下:

  1. 首先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

其包含了三個步驟:

  1. 取出目前items的值
  2. 將目前的值增加1
  3. 重新儲存該值到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造成非預期的結果

參考課程

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!

No responses yet