Горутины синхронизировать/обмениваться данными можно при помощи каналов.
У вас не очень удачный пример для обучения.
Обычно есть горутина или несколько, которые получают данные и пишут их в канал и есть горутина или несколько, которые будут читать из канала.
Читающие горутины будут получать данные из канала в той последовательности, в которой они туда попали.
Ближе к реальности пример будет выглядеть вот так.
Одна горутина пишет данные в канал, а две горутины по очереди извлекают данные.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
num := make(chan int, 1000) // 1000 - размер буффера канала
wg.Add(1)
go func() {
for i := 0; i < 1000; i++ {
num <- i
fmt.Printf("write to channel: %d\n", i)
// задержка нужна только на время теста
time.Sleep(100 * time.Microsecond)
}
close(num)
wg.Done()
}()
wg.Add(1)
go func() {
for {
val, ok := <-num
if !ok {
break
}
fmt.Printf("goroutine 1 got: %d\n", val)
}
wg.Done()
}()
wg.Add(1)
go func() {
for {
val, ok := <-num
if !ok {
break
}
fmt.Printf("goroutine 2 got: %d\n", val)
}
wg.Done()
}()
wg.Wait()
}