package main import ( "fmt" "math/rand" "time" ) type Philo struct { Name string Left Fork Right Fork Bites int MaxDelay time.Duration TimeOut time.Duration } func (p Philo) Delay() { n := rand.Intn(int(p.MaxDelay)) time.Sleep(time.Duration(n)) } func (p Philo) Print(s string) { fmt.Printf("%10s %s\n", p.Name, s) } func (p *Philo) Arrive() stateFn { p.Print("arrives") return p.Hungry } func (p *Philo) Hungry() stateFn { p.Print("is hungry") p.Left.Grab() if ok := p.Right.TryGrab(p.TimeOut); ok { return p.Eat } p.Left.Put() return p.Starve } func (p *Philo) Starve() stateFn { p.Print("is starving") p.Delay() return p.Hungry } func (p *Philo) Eat() stateFn { p.Print("is eating") p.Delay() p.Left.Put() p.Right.Put() if p.Bites--; p.Bites <= 0 { return p.Leave } return p.Think } func (p *Philo) Think() stateFn { p.Print("is thinking") p.Delay() return p.Hungry } func (p *Philo) Leave() stateFn { p.Print("leaves") return nil } type stateFn func() stateFn func (p *Philo) Dine() { for state := p.Arrive; state != nil; { state = state() } }