go开发中sync必备知识,小编总结下,看到的同学有福了……
一、lock
Mutex互斥锁,也是全局锁;Lock()加锁,Unlock()解锁.
func main() {
var l *sync.Mutex
l = new(sync.Mutex)
l.Lock()
defer l.Unlock()
fmt.Println(“1”)
}
RWMutex 读写锁 ,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景.写锁权限高于读锁,有写锁时优先进行写锁定。
基本遵循两大原则:
1、可以随便读,多个goroutine同时读
2、写的时候,啥也不能干。不能读也不能写
RWMutex提供了四个方法:
func (*RWMutex) Lock // 写锁定
func (*RWMutex) Unlock // 写解锁
func (*RWMutex) RLock // 读锁定
func (*RWMutex) RUnlock // 读解锁
二、WaitGroup
WaitGroup等待一组 线程 集合完成,才会继续向下执行。
func main() {
var wg sync.WaitGroup
var urls = []string{
“”,
“”,
“”,
}
for _, url := range urls {
// Increment the WaitGroup counter.
wg.Add(1)
go func(url string) {
// Launch a goroutine to fetch the URL.
defer wg.Done()
// Fetch the URL.
fmt.Println(url)
}(url)
}
// Wait for all goroutines to finish.
wg.Wait()
fmt.Println(“Game Over”)
}
三、条件变量 Cond
等待通知: wait
阻塞当前线程,直到收到该条件变量发来的通知
单发通知: signal
让该条件变量向至少一个正在等待它的通知的线程发送通知,表示共享数据的状态已经改变。
广播通知: Broadcast
让条件变量给正在等待它的通知的所有线程都发送通知。
func NewCond(l Locker) *Cond
func TestCond() {
cond := sync.NewCond(&sync.Mutex{})
for i := 0; i < 10; i++ {
go func(t int) {
time.Sleep(time.Second)
cond.L.Lock()
defer cond.L.Unlock()
cond.Wait()
fmt.Println(t)
}(i)
}
time.Sleep(2 * time.Second)
//cond.Signal()
cond.Broadcast()
}
四、pool 用来保存和复用临时对象,以减少内存分配,降低CG压力。
type Pool
func (p *Pool) Get() interface{}
func (p *Pool) Put (x interface{})
New func() interface{}
Get返回Pool中的任意一个对象。如果Pool为空,则调用New返回一个新创建的对象。如果没有设置New,则返回 nil 。
func TestPool() {
var pool sync.Pool
pool.New = func() interface{} { return “Hello” }
for i := 0; i < 10; i++ {
s := pool.Get()
fmt.Println(s)
pool.Put(“World” + strconv.FormatInt(int64(i), 10))
}
}
五、once 对于从全局的角度只需要运行一次的代码,比如全局初化操始作,go语言提供了一个Once类型来保证全局的唯一性操作
func TestOnce() {
once := &sync.Once{}
for i := 0; i < 10; i++ {
go func(t int) {
once.Do(func() {
fmt.Println(“Hello Once!”)
})
fmt.Println(“Hello World!”)
}(i)
}
time.Sleep(time.Second)
}
更多内容请关注每日编程,每天进步一点。