Go|Go Quiz: 从Go面试题看锁的注意事项
背景
Google工程师Valentin Deleplace出了2道关于锁的题目,拿出来和大家分享下。
题目1
// quiz_lock1.go
package mainimport (
"fmt"
"sync"
)func main() {
var m sync.Mutex
fmt.Print("1, ")
m.Lock()
m.Lock()
m.Unlock()
fmt.Println("2")
}
- A:
1, 2
- B:
1,
- C:
1, fatal error:......
- D: 编译报错
// quiz_lock2.go
package mainimport (
"fmt"
"sync"
"time"
)func main() {
var m sync.Mutex
fmt.Print("1, ")
m.Lock()go func() {
time.Sleep(200 * time.Millisecond)
m.Unlock()
}()m.Lock()
fmt.Println("2")
}
- A:
1, 2
- B:
1,
- C:
1, fatal error:......
- D: 编译报错
如果mutex没有释放,在同一个goroutine就不能对这个mutex加2次锁,否则第2次加锁就会阻塞,如果没有其它goroutine去释放这个mutex,就会导致死锁,出现runtime error:
fatal error: all goroutines are asleep - deadlock!
。同时,sync.Mutex和sync.RWMutex允许一个goroutine对其加锁,其它goroutine对其解锁,不要求加锁和解锁在同一个goroutine里。
所以第一道题目的答案是
C
,第二道题目的答案是A
。思考题
// quiz_lock3.gopackage mainimport (
"fmt"
"sync"
)var a sync.Mutexfunc main() {
a.Lock()
fmt.Print("1, ")
a.Unlock()
fmt.Print("2, ")
a.Unlock()
fmt.Println("3")
}
- A:
1, 2, 3
- B:
1, 2, fatal error:......
- C:
1, 2
- D: 编译报错
mutex
获取答案。总结 Go语言里的锁和C++,Java里的不太一样,给大家总结了以下注意事项
- Go的锁是不可重入的,没有递归锁
- 允许一个goroutine加锁,另一个goroutine解锁,不要求加锁和解锁在同一个goroutine里
- sync.Mutex的零值是没有加锁的Mutex,sync.RWMutex的零值是没有加锁的RWMutex
- 更多细节可以参考References里Mutex和RWMutex的官方说明
公众号:coding进阶。关注公众号可以获取最新Go面试题和技术栈。
个人网站:Jincheng's Blog。
知乎:无忌。
References
- https://github.com/jincheng9/...
- https://twitter.com/val_delep...
- https://twitter.com/val_delep...
- https://pkg.go.dev/sync@go1.1...
- https://pkg.go.dev/sync@go1.1...
推荐阅读
- 尤娜,我去面试了
- 漫画理解redis持久化和主从复制
- 机器学习|从Python入门人工智能指南
- JAVA的自学之路|【Java课程设计】【图形界面程序】【计算器】
- 面试复习|CGB JAVA面试题 NOTE1
- 0510课堂笔记--数组-面向对象
- 学习笔记|JAVA五--面向对象基础
- CGB2202|CGB2202面向对象第4天
- Android面试(4面字节跳动拿到2-2|Android面试:4面字节跳动拿到2-2 Offer)
- 网络安全|2021web安全最全学习路线,从入门到入职(含书籍、工具包)