一、前言
go語言類似Java JUC包也提供了一些列用於多線程之間進行同步的措施,比如低級的同步措施有 鎖、CAS、原子變量操作類。相比Java來說go提供了獨特的基於通道的同步措施。本節我們先來看看go中互斥鎖
二、互斥鎖
互斥鎖是獨佔鎖,同時只有一個線程可以獲取該鎖,其他線程則會被阻塞掛起,等獲取鎖的線程釋放鎖後,阻塞的線程中的一個纔可以被喚醒並獲取鎖。
本節我們使用獨佔鎖來實現一個線程安全的計數器:
package main
import (
"fmt"
"sync"
)
var (
counter int//計數器
wg sync.WaitGroup//信號量
mutex sync.Mutex//互斥鎖
)
func main() {
//1.兩個信號量
wg.Add(2)
//2.開啓兩個線程
go incCounter()
go incCounter()
//3.等待子線程結束
wg.Wait()
fmt.Println(counter)
}
func incCounter() {
defer wg.Done()
//2.1.獲取鎖
mutex.Lock()
//2.2.計數加1
counter++
//2.3.釋放獨佔鎖
mutex.Unlock()
}
- 在go中使用 sync.Mutex 就可以獲取一個開箱即用的互斥鎖
- counter是一個變量,這裏用來存放計數
- wg用來實現主線程等待子線程執行完畢,代碼(2)設置信號爲2,因爲本例子裏面開啓了兩個字線程
- 代碼(2)開啓了兩個子線程,線程內首先獲取互斥鎖,然後累加計數,然後釋放鎖,最後遞減信號量
- 代碼(3)等待子線程執行完畢後返回,然後打印計數
三、總結
go中互斥鎖是獨佔鎖,並且是不可重入鎖,同一個線程並不可獲取同一個鎖多次。