From doc:
If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
One way is to use this. Here's the receiver goroutine is spawned first. Also, if the receiver is not ready yet, default case will be picked up. And if it's ready, the specific case will be ready. If you run this several times, you can see either of cases happening.
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
// goroutine acts as the reciever
go func() {
fmt.Printf("main at %d\n", time.Now().UnixNano())
fmt.Println(<-ch)
}()
go func() {
fmt.Printf("func at %d\n", time.Now().UnixNano())
select {
case ch <- 1:
fmt.Println("running send")
default:
fmt.Println("running default")
}
}()
time.Sleep(1 * time.Second) // Wait for the goroutines
}
Another solution would be to use, buffered channel:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 1)
go func() {
fmt.Printf("func at %d\n", time.Now().UnixNano())
select {
case ch <- 1:
fmt.Println("running send")
default:
fmt.Println("running default")
}
}()
time.Sleep(100 * time.Millisecond)
fmt.Printf("main at %d\n", time.Now().UnixNano())
fmt.Println(<-ch)
}
Also, do read this thread on stackoverflow