Go語言中樂觀鎖與悲觀鎖的具體使用
改變一個數(shù)值的三個步驟
- 把想修改的數(shù)值從某個地方取出來
- 將取出來的數(shù)值修改為期望值
- 把修改后的數(shù)值保存到原來的地方
問題
如果在做第2步時,有另一個過程(進程或線程)對同一個數(shù)值進行同樣的操作(取值、修改),那么當這兩個過程都要做第3步的時候,就肯定有一個過程是白干活的。
悲觀鎖
悲觀的鎖總認為會發(fā)生并發(fā)問題,屬于保守派。
如果想修改一個數(shù)值,立馬給這個數(shù)值上一把鎖,標明這個數(shù)值正在被修改,誰也不能修改了;然后才開始三步走,在三步走的過程結(jié)束以后,再把鎖解除。
當有其他過程想要修改同一個數(shù)值時,看到了鎖就不進行三步走了,而是選擇等待;當鎖被解除了,自己在數(shù)值也加一把鎖,然后開始三步走,在三個步驟走完了,也把鎖解除。
樂觀鎖
樂觀的鎖總認為不會發(fā)生并發(fā)問題,屬于樂天派。
修改數(shù)據(jù)時不加鎖,正常進行1、2步,在進行第3步的時候,確認一下數(shù)值是否進行了修改,如果被修改過,放棄修改,重新走一遍1、2、3步(或者放棄對數(shù)值進行修改)。
Go語言中的樂觀鎖與悲觀鎖
sync/atomic
Go語言有一個atomic包,可以在不形成臨界區(qū)和創(chuàng)建互斥量的情況下完成并發(fā)安全的值替換操作,這個包應(yīng)用的便是樂觀鎖的原理
但是這個包只支持int32/int64/uint32/uint64/uintptr這幾種數(shù)據(jù)類型的一些基礎(chǔ)操作,如增減、交換、載入、存儲等
sync
Go語言中的sync包提供了各種鎖,如果使用了這個包,基本就以悲觀鎖的工作模式了
go代碼示例
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
var (
x int64
mu sync.Mutex
wg sync.WaitGroup
)
// 普通函數(shù), 并發(fā)不安全
func Add() {
x++
wg.Done()
}
// 互斥鎖, 并發(fā)安全,性能低于原子操作
func muAdd() {
mu.Lock()
x++
mu.Unlock()
wg.Done()
}
// 原子操作,并發(fā)安全,性能高于互斥鎖,只針對go中的一些基本數(shù)據(jù)類型使用
func AmAdd() {
atomic.AddInt64(&x, 1)
wg.Done()
}
func main() {
// 原子操作atomic包
// 加鎖操作涉及到內(nèi)核態(tài)的上下文切換, 比較耗時,代價高
// 針對基本數(shù)據(jù)類型我們還可以使用原子操作來保證并發(fā)安全
// 因為原子操作是go語言提供的方法,我們在用戶態(tài)就可以完成,因此性能比加鎖操作更好
// go語言的原子操作由內(nèi)置的庫,sync/atomic完成
start := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
go Add() // 普通版Add函數(shù)不是并發(fā)安全的
// go muAdd() // 加鎖版Add函數(shù),是并發(fā)安全的, 但是加鎖性能開銷大
// go AmAdd() // 原子操作版Add函數(shù),是并發(fā)安全的,性能優(yōu)于加鎖版
}
end := time.Now()
wg.Wait()
fmt.Println(x)
fmt.Println(end.Sub(start))
}
到此這篇關(guān)于Go語言中樂觀鎖與悲觀鎖的具體使用的文章就介紹到這了,更多相關(guān)Go語言 樂觀鎖與悲觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言LeetCode題解999可以被一步捕獲的棋子數(shù)
這篇文章主要為大家介紹了go語言LeetCode題解999可以被一步捕獲的棋子數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Golang中crypto/ecdsa庫實現(xiàn)數(shù)字簽名和驗證
本文主要介紹了Golang中crypto/ecdsa庫實現(xiàn)數(shù)字簽名和驗證,將從ECDSA的基本原理出發(fā),詳細解析如何在Go語言中實現(xiàn)數(shù)字簽名和驗證,具有一定的參考價值,感興趣的可以了解一下2024-02-02
Golang中g(shù)in框架綁定解析json數(shù)據(jù)的兩種方法
本文介紹 Golang 的 gin 框架接收json數(shù)據(jù)并解析的2種方法,文中通過代碼示例介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2023-12-12

