How to Implement Thread-Safety for Variables in Go
In Java, the concept of synchronized variables ensures that only a single thread can execute a specific code block at any given time. However, Go does not offer an explicit synchronized keyword.
Rationale
Go promotes a different approach to thread synchronization, guided by the principle: "Do not communicate by sharing memory; instead, share memory by communicating." This means avoiding direct access to shared memory and opting for communication-based mechanisms like channels.
Mutex-Based Synchronization
Should you encounter a scenario where a mutex is necessary, here's how to implement it in Go:
var ( mu sync.Mutex protectMe int ) func getMe() int { mu.Lock() me := protectMe mu.Unlock() return me } func setMe(me int) { mu.Lock() protectMe = me mu.Unlock() }
Improvements
Atomic Synchronization
If you need to protect a single value, consider using the sync/atomic package:
var protectMe int32 func getMe() int32 { return atomic.LoadInt32(&protectMe) } func setMe(me int32) { atomic.StoreInt32(&protectMe, me) }
Communication-Based Approach
Go encourages using channels for inter-goroutine communication, eliminating the need for shared variables. For example, in a publisher-subscriber pattern:
type topic struct { subscribing []chan int } var t = &topic{} func subscribe() chan int { ch := make(chan int) t.subscribing = append(t.subscribing, ch) return ch } func publish(v int) { for _, ch := range t.subscribing { ch <- v } }
This approach ensures thread-safe communication without sharing memory.
The above is the detailed content of How to Achieve Thread Safety in Go: Mutexes, Atomics, or Channels?. For more information, please follow other related articles on the PHP Chinese website!