高併發之_鎖

提起高併發, 就不得不提 "鎖"的概念

目錄:

初識: 鎖

鎖的實現原理

鎖的優化方向



初識: 鎖

關於鎖,有以下幾個問題
1) 什麼是鎖?

2) 鎖是幹什麼用的?

3) 現成的鎖如何使用?



鎖的實現原理

關於鎖的原理, 有以下幾個問題

1) 鎖的實現流程是什麼?

2) 鎖爲什麼能保證數據安全?



鎖的優化方向

1) 鎖會有什麼弊端麼?

1) 鎖該如何優化?





1) 什麼是鎖?
: 抽象與生活中的概念,即用鎖來鎖住的大門,一般情況下除了有鑰匙的人之外,其他人都進不去.
在編程中也是如此, 由於多線程,產生了高併發, 相當於幾十號人往一個茅坑裏衝,如果不鎖門,那麼少說也會有幾個人同時擠入, 然後拉的到處都是. 那麼這個茅坑就廢了 (如果這種情況你還敢去,本博主願稱你位最強)

2) 鎖是幹什麼用的?
在編程中 “鎖” 就是防止多個線程同時在同時 (此處的同時也可是是運行某一段業務邏輯的時間) 操作一個數據
在生活裏 “鎖” 就是防止多個人衝一間廁所.

假若 削減庫存
最簡單的邏輯是:
選擇 --> 訂單 --> 扣減庫存 --> 支付 --> …
那麼在 減少庫存的時候, 首先拿到庫存數,然後在當前的數量上減去用戶購買的個數.
假設一個用戶下訂單,到訂單完成. 需要1秒中的處理時間, 那麼 60個用戶就需要60秒的處理時間, 也就是說 第61個客戶需要等 1830秒,將近30分鐘 才能等到系統開始處理他的訂單, 而越往後越恐怖.
此時的解決方案之一就是開啓一個線程,相當於有兩個線程在處理當前事務那麼詳單與 1秒處理兩筆訂單. 客戶只要等待15分鐘就可以了.同理線程開的越多處理速度越快
那麼如果在獲取庫存的時候出現併發導致拿到的庫存數一致, 那麼就相當於同一間商品賣出去兩次, 會導致賣出的商品大於庫存的情況.
此時只需要使用鎖把 獲取存款數和扣減庫存數的代碼包裹起來, 形成一個小房間, 當一個線程拿到鑰匙進入其中並再度把門鎖上, 當線程出來之前,別的線程都進不去. 如此方可保證庫存正常

3) 現成的鎖如何使用?
在編程語言中對於鎖的概念都會有封裝, 一般在比較流行的編程語言都會對鎖進行語法封裝.
而如果沒有線程的鎖,那麼只能自己實現鎖的機制. 然後根據你自己的規則來使用了.





1) 鎖的實現流程是什麼?
實現鎖 必須得有兩個前提條件:
1) 共享
2) 互斥
流程如下:
當線程A 拿到鎖C 的時候值爲true,那麼線程A 將鎖置爲false 然後進入 鎖包裹的代碼塊中. 在線程A 出代碼塊之前 鎖C的值一直都會是false
線程B 拿到鎖C的時候 發現 鎖C的值爲false, 那麼就無法進入 代碼塊此時只能沉睡 or 死循環判斷 鎖C的值 什麼時候 爲 true就 跳出去.

在以上的流程中 線程A和線程B 都能拿到鎖C, 這就是 共享
線程A先拿到鎖C就可以進入, 線程B在拿到鎖C時線程A沒有運行完畢那麼 就無法進入 這就是 互斥

2) 鎖爲什麼能保證數據安全?

因爲只要鎖的實現邏輯沒有問題, 功能正常,在鎖包裹的代碼塊中同時只能有一個線程運行,也就在局部不存在多線程的狀況, 如此數據自然不會出錯





1) 鎖會有什麼弊端麼?
鎖的弊端很明顯, 將業務某一塊 由多線程併發變成單線程串行,那麼由多線程帶來的性能在這一塊是不存在的, 會導致性能的下降,如果鎖住的代碼塊過多會導致性能的嚴重下降

1) 鎖該如何優化?
關於鎖的優化可以從兩點入手:
1) 鎖的覆蓋範圍
2) 鎖的實現方式
最理想的狀態莫過於 “無鎖化”, 即不使用線程掛起,喚醒機制 來保證當前的數據在高併發下的安全性

在高併發下只有三種可能性:
1) 只有一個線程運行當前代碼塊
2) 有多個線程交替運行當前代碼塊
3) 有多個線程併發運行當前代碼塊

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