Go语言协程并发---互斥锁sync.Mutex
阅读原文时间:2023年07月08日阅读:1

package main

import (
"fmt"
"sync"
"time"
)

/*
mt.Lock()
抢锁
一次只能被一个协程锁住
其余想要抢到这把锁的协程阻塞等待至前面的协程将锁释放
mt.Lock()的可能性有两种:
①抢到锁,继续向下执行

②没抢到,阻塞等待至前面的协程将锁释放

mt.Unlock()
解锁
锁一旦释放,其他抢这把锁的协程就会得到抢锁机会
*/

func main() {
//声明同步锁
var mt sync.Mutex

var wg sync.WaitGroup  
var money = 2000

for i := 0; i < 10; i++ {  
    wg.Add(1)  
    go func(index int) {  
        fmt.Printf("协程%d开始抢锁\\n",index)

        //抢锁,如果成功,继续向下执行,否则阻塞等待至抢到为止(抢到的人不释放,你就一直阻塞)  
        //所有抢锁的协程都是资源竞争者  
        mt.Lock()

        /\*抢锁成功以后执行对数据的访问\*/  
        fmt.Printf("协程%d抢锁成功!\\n",index)  
        fmt.Printf("协程%d开始操作数据!\\n",index)  
        for j := 0; j < 10000; j++ {  
            money +=1  
        }  
        <-time.After(2\*time.Second)  
        fmt.Printf("协程%d将锁释放!\\n",index)

        //数据操作完毕,将锁释放  
        mt.Unlock()  
        wg.Done()  
    }(i)  
}  
wg.Wait()  
fmt.Println(money)  

}

package main

import (
"fmt"
"sync"
"time"
)

/*
银行账户案例
·创建银行类账户
·存取款方式需要并发安全(不允许并发访问余额)
·查询余额和打印流水可以并发操作
·创建账户实例,并发执行存取款,查询余额,打印流水操作
*/

type Account struct{
money int

//账户的互斥锁  
mt sync.Mutex  

}

/*
存钱:必须保证并发安全,不允许并发操作
*/
func (a *Account)SaveMoney(n int) {
//必须先抢到互斥锁
a.mt.Lock()

fmt.Println("SaveMoney开始")  
<-time.After(3\*time.Second)  
a.money += n  
fmt.Println("SaveMoney结束")

//将锁释放  
a.mt.Unlock()  

}

/*
取钱:必须保证并发安全,不允许并发操作
*/
func (a *Account)GetMoney(n int) {
//必须先抢到互斥锁
a.mt.Lock()

fmt.Println("GetMoney开始")  
<-time.After(3\*time.Second)  
a.money -= n  
fmt.Println("GetMoney结束")

//将锁释放  
a.mt.Unlock()  

}

/*查询余额:可以并发执行*/
func (a *Account)Query() {
fmt.Println("Query开始")
<-time.After(3*time.Second)
fmt.Println("当前余额:",a.money)
fmt.Println("Query结束")
}

///*打印流水:可以并发执行*/
//func (a *Account)PrintHistory() {
// fmt.Println("PrintHistory开始")
// <-time.After(3*time.Second)
// fmt.Println("打印流水")
// fmt.Println("PrintHistory结束")
//}

func main() {
var wg sync.WaitGroup

account := &Account{10000, sync.Mutex{}}

for i := 0; i < 3; i++ {  
    wg.Add(1)  
    go func() {  
        account.SaveMoney(100)  
        wg.Done()  
    }()

}

for i := 0; i < 3; i++ {  
    wg.Add(1)  
    go func() {  
        account.GetMoney(100)  
        wg.Done()  
    }()  
}

for i := 0; i < 3; i++ {  
    wg.Add(1)  
    go func() {  
        account.Query()  
        wg.Done()  
    }()  
}

//for i := 0; i < 3; i++ {  
//  wg.Add(1)  
//  go func() {  
//      account.PrintHistory()  
//      wg.Done()  
//  }()  
//}

wg.Wait()

fmt.Println("main over")  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器