package main
import (
"fmt"
"sync"
"time"
)
func main() {
manager := NewPlatformManager()
pTrain := &Passengertrain{mediator:manager}
mTrain := &MailTrain{mediator:manager}
pTrain.Arrive()
mTrain.Arrive()
pTrain.Depart()
//pTrain.Arrive()
//mTrain.Depart()
//time.Sleep(20000 * time.Millisecond)
}
/*
Mediator pattern
*/
type Train interface {
Arrive()
Depart()
PermitArrival()
}
type Mediator interface {
allowLanding(Train) bool
notifyFree()
}
type Passengertrain struct {
mediator Mediator
}
func (t *Passengertrain) Arrive() {
if !t.mediator.allowLanding(t) {
fmt.Println("Station Busy,passenger train")
} else {
fmt.Println("Landing on station,passenger train")
time.Sleep(3000 * time.Millisecond)
}
}
func (t *Passengertrain) Depart() {
t.mediator.notifyFree()
fmt.Println("leaving station,passenger train")
}
func (t *Passengertrain) PermitArrival() {
fmt.Println("Allowed to arrive,passenger train")
t.Arrive()
}
type MailTrain struct {
mediator Mediator
}
func (t *MailTrain) Arrive() {
if !t.mediator.allowLanding(t) {
fmt.Println("Station Busy,mail train")
} else {
fmt.Println("Landing on station,mail train")
time.Sleep(5000 * time.Millisecond)
}
}
func (t *MailTrain) Depart() {
t.mediator.notifyFree()
fmt.Println("leaving station,mail train")
}
func (t *MailTrain) PermitArrival() {
fmt.Println("Allowed to arrive,mail train")
t.Arrive()
}
type PlatformManager struct {
queue []Train
signal *sync.Mutex
isBlocked bool
}
func NewPlatformManager() Mediator {
instance := &PlatformManager{
queue: make([]Train,0),signal: &sync.Mutex{},isBlocked: false,}
return instance
}
func (pm *PlatformManager) allowLanding(train Train) bool {
pm.signal.Lock()
defer pm.signal.Unlock()
if !pm.isBlocked {
pm.isBlocked = true
return true
}
pm.queue = append(pm.queue,train)
return false
}
func (pm *PlatformManager) notifyFree() {
pm.signal.Lock()
defer pm.signal.Unlock()
if pm.isBlocked {
pm.isBlocked = false
}
if len(pm.queue) > 0 {
nextTrain := pm.queue[0]
pm.queue = pm.queue[1:]
nextTrain.PermitArrival()
}
}
我得到如下错误,我期望代码在单一流程中运行,也没有定义任何go例程。预期的结果应该是passengertrain到达(等待3秒)-> mailTrain要到达(被要求等待)-> passengertrain离开-> mailTrain被通知并到达并等待(5秒)
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_SemacquireMutex(0xc00002c00c,0x486700,0x1)
/usr/local/go-faketime/src/runtime/sema.go:71 +0x47
sync.(*Mutex).lockSlow(0xc00002c008)
/usr/local/go-faketime/src/sync/mutex.go:138 +0xfc
sync.(*Mutex).Lock(...)
/usr/local/go-faketime/src/sync/mutex.go:81
main.(*PlatformManager).allowLanding(0xc000060150,0x4dd220,0xc000010210,0x0)
/tmp/sandbox325139098/prog.go:97 +0x17d
main.(*MailTrain).Arrive(0xc000010210)
/tmp/sandbox325139098/prog.go:63 +0x48
main.(*MailTrain).PermitArrival(0xc000010210)
/tmp/sandbox325139098/prog.go:78 +0x83
main.(*PlatformManager).notifyFree(0xc000060150)
/tmp/sandbox325139098/prog.go:117 +0xbb
main.(*Passengertrain).Depart(0xc000010200)
/tmp/sandbox325139098/prog.go:49 +0x37
main.main()
/tmp/sandbox325139098/prog.go:15 +0x13b