并发示例的值不正确

I'm working through an ebook and here I am doing this code:

func f(n int) {
  for i := 0; i < 10; i++ {
    fmt.Println(n, ":", i)
    amt := time.Duration(rand.Intn(250))
    time.Sleep(time.Millisecond * amt)
  }
}

func ConcurrMain() {
  for i := 0; i < 10; i++ {
    go f(i)
  }
  fmt.Println("hi")
}

The problem is I'm retrieving different values with every run command through goclipse. It seems to work better when i do not execute the sleep command.

In any case, any explanation with step by step i thought would be beneficial in my learning of concurrency

Here's an example of my return value with time sleep:

4 : 0
1 : 0
6 : 0
0 : 0
5 : 0
7 : 0
8 : 0
2 : 0
3 : 0
9 : 0
9 : 1
hi

Then I run it again and I now get with time sleep:

0 : 0
hi
1 : 0

And now a third time and I get with time sleep:

0 : 0
hi

And this time without sleep i get:

1 : 0
1 : 1
1 : 2
1 : 3
1 : 4
1 : 5
1 : 6
1 : 7
1 : 8
3 : 0
3 : 1
4 : 0
4 : 1
4 : 2
9 : 0
6 : 0
6 : 1
6 : 2
2 : 0
2 : 1
2 : 2
2 : 3
2 : 4
2 : 5
2 : 6
2 : 7
2 : 8
2 : 9
7 : 0
7 : 1
7 : 2
7 : 3
7 : 4
7 : 5
7 : 6
5 : 0
5 : 1
5 : 2
5 : 3
5 : 4
5 : 5
5 : 6
5 : 7
5 : 8
5 : 9
9 : 1
1 : 9
8 : 0
3 : 2
hi

I'm using goclipse under windows in case that information is pertinent

UPDATE

It should be noted that this call is called from the main package as:

func main()
{
   lab.ConcurrMain()
}

UPDATE2

I added: var wg sync.WaitGroup outside the func scope. I also addedwg.Add(1)inside theConcurrMainmethod just prior togo f(i), then i also addedwg.Wait()just after theforloop which executes the go functionand then finallywg.Done()inside thef()` method **and that seems to work but that answer wasnt in the ebook so i want to understand.

In go, a program is only running for as long as it's main goroutine is running. That is, the goroutine that originally runs the main function, if this exits, the entire program exits.

In the example you've originally given (the code snippets) there's nothing to enforce when the goroutines that you spin up in ConcurrMain will be scheduled and run. Before you added the sync.WaitGroup the main goroutine can exit before the additional goroutines have been scheduled.

If the main goroutine exits, the entire program exits and the other goroutines will not be executed. The main goroutine will not wait for the other goroutines unless you specifically ask it to, with a wait group.