Golang / GoLang Interfaces and Object Oriented Interview Questions
Are interface values in Go safe to use concurrently?
Interface values are not inherently goroutine-safe. An interface value is a two-word struct (type pointer + data pointer). Assigning to an interface variable is not atomic — a goroutine reading the interface while another is writing it can observe a partially written state (mismatched type and data words).
// RACE CONDITION: assigning interface value from multiple goroutines var handler http.Handler // goroutine 1: go func() { handler = &MyHandlerA{} }() // goroutine 2: go func() { handler = &MyHandlerB{} }() // goroutine 3 (reader): go func() { handler.ServeHTTP(w, r) }() // may see inconsistent type+data words // Detection: go test -race finds this immediately // Fix 1: protect with sync.Mutex var mu sync.Mutex var safeHandler http.Handler setHandler := func(h http.Handler) { mu.Lock() safeHandler = h mu.Unlock() } getHandler := func() http.Handler { mu.Lock() defer mu.Unlock() return safeHandler } // Fix 2: atomic.Value (stores interface{} / any atomically) var atomicHandler atomic.Value atomicHandler.Store(http.Handler(&MyHandlerA{})) h := atomicHandler.Load().(http.Handler) // atomic read h.ServeHTTP(w, r) // Note: atomic.Value requires all stored values to be the same concrete type // or the same interface type across calls
atomic.Value (since Go 1.4) is the idiomatic way to atomically swap an interface value: it is faster than a mutex for read-heavy scenarios (like a config that is rarely updated but read on every request). All Store calls must store values of the same concrete type.
More Related questions...