JSTAcademy
0 XP
Dashboard
Crash Courses
Goroutines & Channels
40 min
Masters+180 XP
Crash Courses · Masters

Goroutines & Channels

Lightweight concurrency, communication, and synchronization
40 min read+180 XP on completionCert: Go Crash Course
Tap any word in the text below to start reading from there.

Goroutines & Channels

Launching a Goroutine

package main

import (
    "fmt"
    "time"
)

func sayHello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func main() {
    go sayHello("Alice") // runs concurrently
    go sayHello("Bob")
    time.Sleep(100 * time.Millisecond) // crude sync — don't do this in production
}

Channels

Channels replace shared memory. Send with <- and receive with <-:

ch := make(chan int) // unbuffered

go func() {
    ch <- 42 // send (blocks until receiver is ready)
}()

v := <-ch // receive (blocks until sender sends)
fmt.Println(v) // 42

WaitGroup (production sync)

package main

import (
    "fmt"
    "sync"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // decrement counter when done
    fmt.Printf("Worker %d finished\n", id)
}

func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }
    wg.Wait() // blocks until all Done() calls are made
    fmt.Println("All workers finished")
}

Buffered Channels

ch := make(chan string, 3) // buffer of 3

ch <- "a" // does not block
ch <- "b"
ch <- "c"
// ch <- "d" // would block — buffer full

fmt.Println(<-ch) // a
fmt.Println(<-ch) // b

select Statement

func main() {
    ch1 := make(chan string, 1)
    ch2 := make(chan string, 1)

    ch1 <- "one"
    ch2 <- "two"

    select {
    case msg := <-ch1:
        fmt.Println("Received from ch1:", msg)
    case msg := <-ch2:
        fmt.Println("Received from ch2:", msg)
    }
}

Mutex for Shared State

When goroutines share mutable state, protect it with a mutex:

type SafeCounter struct {
    mu sync.Mutex
    v  map[string]int
}

func (c *SafeCounter) Inc(key string) {
    c.mu.Lock()
    c.v[key]++
    c.mu.Unlock()
}

Closing Channels & Range

ch := make(chan int, 5)
for i := 0; i < 5; i++ { ch <- i }
close(ch)

for v := range ch { // loops until channel is closed
    fmt.Println(v)
}
0%