社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
sync.Mutex
sync.Mutex 只有两个公开的指针方法 Lock() 和 Unlock().
Lock() 用于锁定当前互斥量.
Unlock() 用于对互斥量解锁.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mutex sync.Mutex
fmt.Println("加锁. (main)")
mutex.Lock()
fmt.Println("锁上了 (main)")
go func() {
fmt.Println("加锁 (goroutine)")
mutex.Lock() // 对已经加锁的mutex进行重复加锁
fmt.Println("锁上了 (goroutine)")
}()
time.Sleep(time.Second)
fmt.Println("解锁了 (main)")
mutex.Unlock()
time.Sleep(time.Second)
fmt.Println("main exit")
}
演示结果:
分析:
1. 首先main线程进行加锁, 加锁后启动了goroutine,main线程睡1秒,保证goroutine运行起来.
2. goroutine启动后, 进行重复加锁操作,导致 goroutine自身阻塞了.
3. main醒来后解锁,又睡1秒,为了等待goroutine运行. goroutine加锁成功,然后打印 “锁上了 (goroutine)”后就销毁了.
4. main醒来后,打印 “main exit.” 后退出.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mutex sync.Mutex
fmt.Println("加锁. (main)")
mutex.Lock()
fmt.Println("锁上了 (main)")
for i := 1; i <= 3; i++{
go func(i int) {
fmt.Printf("加锁 (g%d)n", i)
mutex.Lock() // 对已经加锁的mutex进行重复加锁
fmt.Printf("锁上了 (g%d)n", i)
}(i)
}
time.Sleep(time.Second) // 等待所有goroutine都运行起来
fmt.Println("解锁了 (main)")
mutex.Unlock()
time.Sleep(time.Second) // 等待goroutine重新锁定互斥锁,只有一个能抢到互斥锁
fmt.Println("main exit")
}
运行结果:
package main
import (
"fmt"
"sync"
)
func main() {
defer func() {
fmt.Println("尝试恢复panic.")
if p := recover(); p != nil {
fmt.Println("已经恢复了 panic")
}
}()
var mutex sync.Mutex
fmt.Println("加锁")
mutex.Lock()
fmt.Println("锁上了")
fmt.Println("解锁")
mutex.Unlock()
fmt.Println("解锁了")
fmt.Println("再解锁")
mutex.Unlock()
}
结果:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!