package main
import (
	"fmt"
	"sync"
	"time"
)
type BankAccount struct {
	balance int
	updated bool
	mu      sync.Mutex
	cond    *sync.Cond
}
func New(startingBalance int) *BankAccount {
	b := &BankAccount{
		balance: startingBalance,
		updated: false,
	}
	b.cond = sync.NewCond(&b.mu)
	return b
}
func (b *BankAccount) addSomeMoney() {
	// It takes a long time to transfer some money.
	time.Sleep(2 * time.Second)
	b.mu.Lock()
	defer b.mu.Unlock()
	b.balance += 100
	b.updated = true
	b.cond.Signal()
}
func main() {
	b := New(10)
	fmt.Println("i am starting with 10 dollars and need to make a deposit...")
	go b.addSomeMoney()
	// Now we have to lock the conditional variable to see if we are updated yet.
	// We need to lock here in order to synchronize access to updated.
	b.cond.L.Lock()
	for !b.updated {
		// Block this thread.
		b.cond.Wait()
	}
	// The conditional variable is locked here so we can print out our new balance.
	fmt.Printf("i now have %d dollars in the bank\n", b.balance)
	// We are done, so unlock and return.
	b.cond.L.Unlock()
}