碼農翻身之我是一個線程 --- 讀書筆記

碼農翻身之我是一個線程

1. "我"的宿命 ----> 處理包裹

1.1 計算機世界規則

  1. 不知何時被選中執行任務
  2. 執行過程中隨時可能被打斷
  3. 有硬盤、數據庫等耗時操作需要讓出CPU等待
  4. 數據來了也得等CPU挑選

1.2 "我"的處理流程圖

"我"的處理流程圖

2. "我"的小夥伴們

  1. Memcached 線程: 分佈式緩存用戶數據
  2. 數據庫連接線程: 他們也有一個線程池

3. "鎖"出的問題

3.1 存取款操作需加鎖後執行,例如:

1 沒加鎖時操作情況

線程1:存入300元 線程2:取出200元
獲取當前餘額:1000 ——
計算最新餘額:1000 + 300 = 1300 ——
線程中斷,等待下次系統挑中執行 ——
—— 獲取當前餘額:1000
—— 計算最新餘額:1000 - 200 = 800
—— 線程中斷,等待下次被系統挑中執行
再次執行,更新餘額:1300 ——
—— 再次執行,更新餘額:800 (存的錢丟了)

2 加鎖時操作情況

線程1:存入300元 線程2:取出200元
獲取賬戶A的鎖:成功 ——
獲取當前餘額:1000 ——
計算最新餘額:1000 + 300 = 1300 ——
線程中斷,等待下次系統挑中執行 ——
—— 獲取賬戶A的鎖:失敗,進入阻塞狀態
被系統選中,更新餘額:1300 ——
釋放賬戶A的鎖 ——
—— 獲取賬戶A的鎖:成功
—— 獲取當前餘額:1300
—— 計算最新餘額:1300 - 200 = 1100
—— 更新餘額:1100
—— 釋放賬戶A的鎖

3.2 死鎖的發生

見下圖:

線程1:演員 -> 導演 線程2:導演 -> 演員
獲取演員的鎖:成功 ——
線程中斷,等待下次系統挑中執行 ——
—— 獲取導演的鎖:成功
—— 線程中斷,等待下次系統挑中執行
獲取導演的鎖:失敗,繼續等待 ——
—— 獲取演員的鎖:失敗,繼續等待

最終只好幹掉一個線程,來保證正常執行

3.3 死鎖的解決:新規則

至此,新建立一個規則:獲取資源的鎖之前,必須先讓所有資源統一進入一個算法,計算資源的優先級;並且永遠按照從小到大的方式獲取鎖。如下表所示:

PS: 這裏假設導演的優先級大於演員的優先級

線程1:演員 -> 導演 線程2:導演 -> 演員
獲取導演的鎖:成功 ——
線程中斷,等待下次系統挑中執行 ——
—— 獲取導演的鎖:失敗,繼續等待
獲取演員的鎖:成功 ——
執行轉賬 ——
釋放演員的鎖 ——
釋放導演的鎖 ——
—— 獲取導演的鎖:成功
—— 獲取演員的鎖:成功
—— 執行轉賬
—— 釋放演員的鎖
—— 釋放導演的鎖
注意:1. 釋放鎖的時候最好是從優先級小的資源開始釋放
     2. 所謂優先級的大小,實際就是將該資源變成一個數來比較,例如,用字符串的hashcode來比較。

後續內容更加精彩,江湖再見~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章