golang协程并发同步-死锁问题

死锁产生条件:互斥,占有并等待,不可抢占,循环等待

type Account struct {
	Id string
	Balance float64
	lock sync.Mutex
}
func (a *Account) deposit(amount float64){
	a.Balance += amount

}
func (a *Account) withdrew(amount float64){
	a.Balance -= amount
}
func main(){
	wg := sync.WaitGroup{}
	wg.Add(2)
	a := Account{
		Id:"1",
		Balance:1000,
		lock:sync.Mutex{},
	}
	b := Account{
		Id:"2",
		Balance:1000,
		lock:sync.Mutex{},
	}
	//死锁示例
	go transfer(&a,&b,100,&wg)//a->b 100
	go transfer(&b,&a,300,&wg)//b->a 300
	wg.Wait()//死锁
	//正确做法,每次都锁住相同用户
	go transfer(&a,&b,100,&wg)//a->b 100
	go transfer2(&b,&a,300,&wg)//b->a 300
	wg.Wait()
	fmt.Println(a.Balance,b.Balance)
}

func transfer(from *Account,to *Account,amount float64,wg *sync.WaitGroup){
	from.lock.Lock()
	time.Sleep(1*time.Second)//等待另一协程锁住另一个用户
	from.withdrew(amount)
	to.lock.Lock()
	to.deposit(amount)
	from.lock.Unlock()
	to.lock.Unlock()
	wg.Done()
}

func transfer2(from *Account,to *Account,amount float64,wg *sync.WaitGroup){
	to.lock.Lock()
	time.Sleep(1*time.Second)
	to.deposit(amount)
	from.lock.Lock()
	from.withdrew(amount)
	to.lock.Unlock()
	from.lock.Unlock()
	wg.Done()
}

你可能感兴趣的:(golang协程并发同步)