Goroutines并发的Go例子

I'm new to the Go Language, and learning here: https://tour.golang.org/concurrency/1

When I run https://play.golang.org/p/9JvbtSuv5o the result is:

world
hello
hello

So Added sync.WaitGroup: https://play.golang.org/p/vjdhnDssGk

package main

import (
    "fmt"
    "sync"
    "time"
)

var w sync.WaitGroup

func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
    w.Done()
}

func main() {
    w.Add(1)
    go say("world")
    say("hello")
    w.Wait()
}

But the result is same:

world
hello
hello

What is wrong with my code?

Please help,
Thank you for your help.

w.Done() decrements the WaitGroup counter.
So your code even sometimes panic: sync: negative WaitGroup counter.

You have two Goroutines:
1 - go say("world")
2 - say("hello") inside main Goroutine
so use w.Add(2), see this working sample (The Go Playground):

package main

import (
    "fmt"
    "sync"
    "time"
)

var w sync.WaitGroup

func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
    w.Done()
}

func main() {
    w.Add(2)
    go say("world")
    say("hello")
    w.Wait()
}

output:

world
hello
hello
world

I hope this helps.

You're only adding 1 to the WaitGroup, but calling Done from 2 invocations of say.

In your example, starting the WaitGroup with 2 would work

w.Add(2)

Problem occurs due to unconditional call to w.Done(). So when u called say("hello") this also decremented counter for waitGroup.

Refer https://play.golang.org/p/wJeAyYyjA2

    package main

    import (
        "fmt"
        "sync"
        "time"
    )

    var w sync.WaitGroup

    func say(s string, async bool) {
        if async {
            defer w.Done()
        }
        for i := 0; i < 2; i++ {
            time.Sleep(100 * time.Millisecond)
            fmt.Println(s)
        }
    }

    func main() {
        w.Add(1)
        go say("world", true)
        say("hello", false)
        w.Wait()
    }