Sync Primitives

sync.Once, sync.RWMutex, sync.Pool, and atomic operations.

package main

import (
	"bytes"
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	// sync.Once — run exactly once
	fmt.Println("--- sync.Once ---")
	var once sync.Once
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			once.Do(func() { fmt.Printf("initialized by goroutine %d\n", id) })
		}(i)
	}
	wg.Wait()

	// sync.RWMutex — concurrent readers
	fmt.Println("\n--- sync.RWMutex ---")
	var mu sync.RWMutex
	data := map[string]int{"a": 1, "b": 2}

	for i := 0; i < 3; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			mu.RLock()
			defer mu.RUnlock()
			fmt.Printf("reader %d: a=%d\n", id, data["a"])
		}(i)
	}
	wg.Wait()

	mu.Lock()
	data["a"] = 99
	mu.Unlock()
	fmt.Println("writer updated a to", data["a"])

	// sync.Pool — reuse objects
	fmt.Println("\n--- sync.Pool ---")
	pool := sync.Pool{New: func() any { return new(bytes.Buffer) }}
	buf := pool.Get().(*bytes.Buffer)
	buf.WriteString("pooled buffer")
	fmt.Println(buf.String())
	buf.Reset()
	pool.Put(buf)

	// sync/atomic — lock-free counter
	fmt.Println("\n--- atomic ---")
	var counter atomic.Int64
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			counter.Add(1)
		}()
	}
	wg.Wait()
	fmt.Println("counter:", counter.Load())
}
▶ Open Go Playground

Copy the code above and paste to run

© 2026 ByteLearn.dev. Free courses for developers. · Privacy