Yes, if only those 3 methods access the count field, your decision is safe to use from multiple goroutines at the same time.
But be aware that the value returned by Status.Get() may be "deprecated" by the time you try to use it. For instance:.
s := &Status{} if s.Get() == 3 { fmt.Println(s.Get()) // This may or may not print 3 } // Or c := s.Get() fmt.Println(c == s.Get()) // This may or may not print true
The above example may or may not print 3 and true , since the second call to s.Get() may precede another call to s.Add() in another goroutine.
If you need a guarantee that no one else changes or accesses the value of the Status.count field while you perform further calculations on it, sync.Mutex or sync.RWMutex , since you can hold the lock in the count field while you finish the calculations.
Edit: To respond to your edit:
Direct access to s.count not secure, atomic.LoadUint32(&s.count) is safe. The reason is that if goroutine # 1 calls s.Add() and goroutine # 2 tries to access s.count , there is no guarantee that goroutine # 2 will see the changes made by # 1. In # 2 you can only see the cached s.count version.
Without explicit synchronization, you cannot observe changes made to a variable in another goroutine. Direct access to s.count is unsynchronized access. Using channels or other synchronization primitives (for example, sync or sync/atomic ) provides sequential access to s.count , therefore, in these solutions the current updated value will always be displayed.
See this article for more details: Go memory model
source share