【GO】6.锁

  • 1.互斥锁:sync.Mutex

当多个线程同时修改一个公共资源时,需要进行同步控制

import "sync"

var {
    mu sync.Mutex
    balance int
}

func Deposit(amount int){
    mu.lock()
    defer mu.Unlock()
    balance = balance + amount
}

func Balance() int{
    mu.lock()
    b := balance
    mu.Unlock()
    return b
}

代码中对临界资源的修改和读取使用互斥锁进行保护,防止并发数据异常。

 

  • 2.读写互斥锁:sync.RWMutex

调用RLock和RUnlock方法来分别获取和释放一个读锁(也称为共享锁)。通过Lock和Unlock来分别获取和释放一个写锁(也称为互斥锁)。

import "sync"

var {
    mu sync.RWMutex
    balance int
}

func Deposit(amount int){
    mu.lock()
    defer mu.Unlock()
    balance = balance + amount
}

func Balance() int{
    mu.Rlock()
    b := balance
    mu.RUnlock()
    return b
}

 

  • 3.延迟初始化:sync.Once

sync.Once可以保证一个Once实例的Do方法只会执行一次,无论Do里的func有多个或者一个,利用这个特性来实现设计模式里的单例模式,注意要确保执行Do的Once实例是同一个。

type singleton struct{}

var {
    ins *singleton
    once sync.Once 
}

func GetIns() *singleton {  
    once.Do(func(){  
        ins = &singleton{}       
    })
    return ins
}

这是单例模式在go语言下最优雅的写法

 

  • 4.并发控制:sync.WaitGroup

开发过程中,经常task之间的同步问题。例如,多个子task并发完成一部分任务,主task等待他们最后结束。

下面代码如果不加WaitGroup,可能不会打印出数字,因为还没等协程执行主线程已经返回,导致协程不会执行。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func PrintInt(num int) {
	fmt.Println(num)
	wg.Done()
}

func main() {
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go PrintInt(i)
	}
	wg.Wait()
}

注意
WaitGroup变量定义后,是不允许被拷贝的,即不允许作为函数参数或者赋值给其他变量。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值