func (acc *ConcurrentAccount) Deposit(amount uint) {
acc.deposits <- amount
}
func (acc *ConcurrentAccount) Withdraw(amount uint) {
acc.withdrawals <- amount
}
访问和修改是通过消息和控制流程通信。
在控制流程中任何访问和修改的动作都是相继发生的。
当控制流程接收到访问或者修改的请求后会立即执行相关动作。让我们仔细看看这个流程:
func (acc *ConcurrentAccount) listen() {
// 执行控制流程
go func() {
for {
select {
case amnt := <-acc.deposits:
acc.account.Deposit(amnt)
case amnt := <-acc.withdrawals:
acc.account.Withdraw(amnt)
case ch := <-acc.balances:
ch <- acc.account.Balance()
}
}
}()
}
select 不断地从各个通道中取出消息,每个通道都跟它们所要执行的操作相一致。
重要的一点是:在 select 声明内部的一切都是相继执行的(在同一个处理程序中排队执行)。一次只有一个事件(在通道中接受或者发送)发生,这样就保证了同步访问共享资源。
领会这个有一点绕。
让我们用例子来看看 Balance() 的执行情况:
一张附属卡的流程 | 控制流程
----------------------------------------------
1. b.Balance() |
2. ch -> [acc.balances]-> ch
3. <-ch | balance = acc.account.Balance()
4. return balance <-[ch]<- balance
5 |
这两个流程都干了点什么呢?
附属卡的流程
1.调用 b.Balance()
2.新建通道 ch,将 ch 通道塞入通道 acc.balances 中与控制流程通信,这样控制流程也可以通过 ch 来返回余额
3.等待 <-ch 来取得要接受的余额
4.接受余额










