golang:协程和通道的奇怪问题

I wrote a test code, but do not understand why I get this result.

My sub() should update or return counter, based on the channel value

send 1 = counter++
send 0 = return counter

I start 10 go routines con(). They should simply send many 1 to channel (this increase counter)
I wait 1 sec and send 0 to channel. What value should I get?

I think first, I get a "random" value, but i get 100000 (ok 10x 10000 is faster than 1 sec)

Now I change

for i:=0; i < 10; i++ {

to

for i:=0; i < 10000; i++ {

and now my returned value is 1

Why!?

Now uncomment fmt.Println(counter) in main(). As you see counter works and has this "random" number

package main

import (
    "fmt"
    "time"
)

var ch chan int = make(chan int)
var counter int

func main() {
    go sub()

    for i:=0; i < 10; i++ { //change to 10000
        go con()
    }

    time.Sleep(1000 * time.Millisecond)

    ch <- 0
    fmt.Println(<- ch)
    //fmt.Println(counter) //uncomment this
}

func sub() {
    for c := range ch {
        if c == 0 { ch <- counter }
        if c == 1 { counter++ }
    }
}

func con() {
    for i := 0; i < 10000; i++ {
        ch <- 1
    }
}

with 2 channels, this work:

package main

import (
    "fmt"
    "time"
)

var ch chan int = make(chan int)
var ch2 chan int = make(chan int)
var counter int

func main() {
    go sub()

    for i:=0; i < 10000; i++ { //change to 10000
        go con()
    }

    time.Sleep(1000 * time.Millisecond)

    ch2 <- 0
    fmt.Println(<- ch2)
    //fmt.Println(counter) //uncomment this
}

func sub() {
    for ;; {
        select {
        case <- ch:
            counter++
        case <- ch2:
            ch2 <- counter
        }
    }
}

func con() {
    for i := 0; i < 10000; i++ {
        ch <- 1
    }
}