java高并發解決方案悲觀鎖樂觀鎖redis鎖

1. 理解同步和異步

同步:一件事一件事的做,做這件事的時候,不能干其他事情

異步:做一件事的同時,可以做其他事情。很多事情可以同時進行

2. 臟數據

當一個事務正在操作數據庫時,數據還沒有提交,這時,另外一個事務也訪問了這個數據庫,然后使用了這個數據,由于訪問的并不是最新的數據,那么這個讀取的操作可能是不正確的,讀到的這個數據就是“臟數據”。

3. 同步(synchronized)處理并發

在方法名前面加上synchronized關鍵字,或者使用同步鎖lock,即可實現同步。

原理:當A事務在處理這件事情的時候,其他的事務只能等待A事務處理完了才能進行處理。

優點:能簡單快速的處理并發問題

缺點:

1. 在單機中:由于A事務在進行,其他很多事務都要排隊等待,必將使得執行速度變慢,損耗性能。

2. 在分布式中:單個程序中事務的同步并不能使其他的程序事務進行等待,起不到應有的作用。

4. 悲觀鎖和樂觀鎖(針對于數據庫)

悲觀鎖:鎖定數據庫中當前事務要操作的數據,在該數據操作完成后,其他操作才能對數據庫進行訪問。

實現方法:在sql后面加上 for update或者for update nowait

for update和for update nowait區別:

1. for update 鎖定當前操作數據,其他事務等待

2. for update nowait鎖定當前數據,其他事務發現數據被鎖定,立即返回"ORA-00054錯誤,內容是資源正忙, 但指定以 NOWAIT 方式獲取資源"

例如:select * from account where name="何紅乾" for update

優點:無論是在單機還是分布式中,只要使用的是同一個數據庫,那么悲觀鎖就能起到作用。

缺點:鎖定數據后,必將影響其他操作,在大流量的情況下,操作速度變慢

樂觀鎖: 采取版本控制方法,只有當要修改的數據版本高于目前存儲的數據版本時,才能操作。

實現方法:在表中增加一個字段version,查詢表中數據時,獲取version版本號,版本號+1,修改表中數據時核對version版本號是否大于存儲的版本號,如果是則操作成功,否則失敗。

優點:可以多個事務同時進行,然后根據返回的不同結果做相應的操作,避免了長事務中的數據庫加鎖開銷。

缺點: 樂觀鎖機制往往基于系統中的數據存儲邏輯,因此也具備一定的局 限性,如在上例中,由于樂觀鎖機制是在我們的系統中實現,來自外部系統的用戶 余額更新操作不受我們系統的控制,因此可能會造成臟數據被更新到數據庫中。在 系統設計階段,我們應該充分考慮到這些情況出現的可能性,并進行相應調整(如 將樂觀鎖策略在數據庫存儲過程中實

現,對外只開放基于此存儲過程的數據更新途 徑,而不是將數據庫表直接對外公開)

5. redis緩存

1. redis不同于mysql,它是完全基于內存的,絕大部分請求是純粹的內存操作,非常快速。數據存在內存中,類似于HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1);

2. 數據結構簡單,對數據操作也簡單,Redis中的數據結構是專門進行設計的;

3. 采用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的性能消耗;

4. 使用多路I/O復用模型,非阻塞IO;

多路I/O復用模型:多路I/O復用模型是利用 select、poll、epoll 可以同時監察多個流的 I/O 事件的能力,在空閑的時候,會把當前線程阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,于是程序就會輪詢一遍所有的流(epoll 是只輪詢那些真正發出了事件的流),并且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。

這里“多路”指的是多個網絡連接,“復用”指的是復用同一個線程。采用多路 I/O 復用技術可以讓單個線程高效的處理多個連接請求(盡量減少網絡 IO 的時間消耗),且 Redis 在內存中操作數據的速度非???,也就是說內存內的操作不會成為影響Redis性能的瓶頸,主要由以上幾點造就了 Redis 具有很高的吞吐量

5. 使用底層模型不同,它們之間底層實現方式以及與客戶端之間通信的應用協議不一樣,Redis直接自己構建了VM 機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求;

6. redis分布式鎖(基于setnx(),expire()方法)

setnx(key,value),如果key不存在,則設置key-value成功,返回1;如果key存在,則返回0。

expire()設置過期時間

實現方法:

1. setnx(lockkey, 1) 如果返回 0,則說明占位失??;如果返回 1,則說明占位成功

2. expire() 命令對 lockkey 設置超時時間,為的是避免死鎖問題。

3. 執行完業務代碼后,可以通過 delete 命令刪除 key。

優點:簡單易實現,能解決日常工作需求。

缺點: 如果執行完setnx()方法后,在expire()方法執行前發生了宕機,那么就會出現死鎖。

7. redis分布式鎖(基于setnx(),get(),getset()方法)

get(key),獲取key對應的value。

getset(key,value1),返回null此時key的值會被設置為value1.

getset(key,value2),? 返回null此時key的值會被設置為value2.

實現方法:

1. setnx(lockkey, 當前時間+過期超時時間),如果返回 1,則獲取鎖成功;如果返回 0 則沒有獲取到鎖,則進行其他操作

2. get(lockkey) 獲取值 oldExpireTime ,并將這個 value 值與當前的系統時間進行比較,如果小于當前系統時間,則認為這個鎖已經超時,可以允許別的請求重新獲取,進行其他操作。

3. 計算 newExpireTime = 當前時間+過期超時時間,然后 getset(lockkey, newExpireTime) 會返回當前 lockkey 的值currentExpireTime。

4. 判斷 currentExpireTime 與 oldExpireTime 是否相等,如果相等,說明當前 getset 設置成功,獲取到了鎖。如果不相等,說明這個鎖又被別的請求獲取走了,那么當前請求可以直接返回失敗,或者繼續重試。

5. 在獲取到鎖之后,當前線程可以開始自己的業務處理,當處理完畢后,比較自己的處理時間和對于鎖設置的超時時間,如果小于鎖設置的超時時間,則直接執行 delete 釋放鎖;如果大于鎖設置的超時時間,則不需要再鎖進行處理。

優點:能夠防止setnx(),expire()方式出現的死鎖問題

缺點: 不太清楚

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380