1.乌龟每秒跑10cm,兔子每秒跑20cm;
2.兔子看到乌龟比自己落后1m,就开始睡20s.
3.跑道20m长
问最后谁赢了?
其实在go语言实现一个多线程不要太简单,不过人家叫做协程。用关键字go 就可以开启协程,多协程中通信用到最方便的方式还是channel。话不多说上代码
package main
import (
"fmt"
"sync"
"time"
)
//同步标志
var wg sync.WaitGroup
//跑道20m
var total = 2000
//落后1m
var distance = 100
//兔子每秒跑20cm
var rabbitSpeed = 20
//睡20s
var rabbitSleepCount = 20
//乌龟每秒跑10cm
var tortoiseSpeed = 10
func main() {
wg.Add(2)
fmt.Printf("赛道总长 %d cm,兔子速度 %d cm/s乌龟速度 %d cm/s\n",total,rabbitSpeed,tortoiseSpeed)
fmt.Print("比赛开始------\n")
//构建通道传递乌龟距离
t := make(chan int, 20)
go rabbit(t)
go tortoise(t)
wg.Wait()
close(t)
}
//兔子
func rabbit(t chan int) {
fmt.Print("兔子起跑\n")
var cm = 0
var sleepCount = 0
for true {
time.Sleep(time.Second * 1)
//获取乌龟的距离
v := <-t
//睡觉未结束
if sleepCount > 0 {
sleepCount--
//继续下次
fmt.Printf("兔子睡觉 %d s\n", rabbitSleepCount-sleepCount)
continue
}
//每秒跑20cm
cm += rabbitSpeed
fmt.Printf("兔子跑了 %d cm\n", cm)
//跑完停止 20*100cm
if cm >= total {
fmt.Print("兔子到达终点\n")
wg.Done()
break
}
//落后1m *100
if cm-v >= distance {
sleepCount = rabbitSleepCount
fmt.Print("兔子开始睡觉\n")
}
}
}
//乌龟
func tortoise(t chan int) {
var cm = 0
fmt.Print("乌龟起跑\n")
for true {
time.Sleep(time.Second * 1)
//每秒跑10cm
cm += tortoiseSpeed
fmt.Printf("乌龟跑了 %d cm\n", cm)
t <- cm
//跑完停止 20*100cm
if cm >= total {
fmt.Print("乌龟到达终点\n")
wg.Done()
break
}
}
}
结果如下
补记,这个使用chanel是一种解法,还有一种,使用共享变量
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
var distance int32 = 0
var waitFlag sync.WaitGroup
var runFlag sync.WaitGroup
var lock sync.Mutex
//跑道20m
const total int32 = 2000
const timerIntervals = time.Second *1
//动物接口
type Animal interface {
run()
}
//兔子对象
type Rabbit struct {
speed int32
distance int32
sleepCount int32
}
func (r Rabbit) run(){
var cm int32 = 0
fmt.Print("兔子就绪\n")
runFlag.Wait()
fmt.Print("兔子起跑\n")
var sleepCount int32 = 0
for true {
time.Sleep(timerIntervals * 1)
//获取乌龟的距离
var v = getDistance()
//睡觉未结束
if sleepCount > 0 {
sleepCount--
//继续下次
fmt.Printf("兔子睡觉 %d s\n", r.sleepCount-sleepCount)
continue
}
//每秒跑20cm
cm += r.speed
fmt.Printf("兔子跑了 %d cm\n", cm)
//跑完停止 20*100cm
if cm >= total {
fmt.Println("兔子到达终点",time.Now())
waitFlag.Done()
break
}
//落后1m *100
if cm-v>= r.distance {
sleepCount = r.sleepCount
fmt.Print("兔子开始睡觉\n")
}
}
}
type Tortoise struct {
speed int32
}
func (t Tortoise) run(){
var cm int32 = 0
fmt.Print("乌龟就绪\n")
runFlag.Wait()
fmt.Print("乌龟起跑\n")
for true {
time.Sleep(timerIntervals)
//每秒跑10cm
cm += t.speed
fmt.Printf("乌龟跑了 %d cm\n", cm)
pullDistance(t.speed)
//跑完停止 20*100cm
if cm >= total {
fmt.Println("乌龟到达终点",time.Now())
waitFlag.Done()
break
}
}
}
func main() {
waitFlag.Add(2)
runFlag.Add(1)
var rabbit Rabbit
rabbit.speed = 20
rabbit.distance = 100
rabbit.sleepCount = 20
var tortoise Tortoise
tortoise.speed = 10
fmt.Println("比赛开始",time.Now())
go rabbit.run()
go tortoise.run()
runFlag.Done()
waitFlag.Wait()
}
func getDistance() int32 {
var v int32
lock.Lock()
v = distance
lock.Unlock()
return v
}
func pullDistance(v int32){
lock.Lock()
atomic.AddInt32(&distance,v)
}