package main import ( "fmt" "math/rand" "sync" "time" ) var mu sync.Mutex type queue struct { size int load []int } func remove(s []int, i int) []int { copy(s[i:], s[i+1:]) return s[:len(s)-1] } func work(q *queue) <-chan string { ch := make(chan string) go func() { for { mu.Lock() curLoad := len(q.load) mu.Unlock() if curLoad > 0 { mu.Lock() curValue := q.load[0] mu.Unlock() time.Sleep(time.Millisecond * time.Duration(curValue)) mu.Lock() q.load = remove(q.load, 0) mu.Unlock() ch <- "finished" } } }() return ch } func load(q *queue) { go func() { for { time.Sleep(time.Millisecond * time.Duration(rand.Intn(1000))) mu.Lock() q.load = append(q.load, rand.Intn(1000)) mu.Unlock() } }() } func init() { rand.Seed(time.Now().UnixNano()) } func main() { q := queue{ size: 10, } load(&q) ch := work(&q) for { select { case <-ch: fmt.Println("finished something") } } }