Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/threadsafe"
Package threadsafe defines lock interfaces for building reusable, goroutine-safe data structures and helpers without hard-coding a concrete lock type.
It defines two lock interfaces:
- [Locker]: the write-lock contract (
LockandUnlock), a defined type sharing the method set ofsync.Locker. - [RLocker]: the read-lock contract (
RLockandRUnlock) used by read/write synchronization patterns.
These interfaces are embedded or referenced by concurrent containers and utility types used across multiple goroutines.
Usage
See the examples in:
- github.com/tecnickcom/nurago/pkg/threadsafe/tsmap
- github.com/tecnickcom/nurago/pkg/threadsafe/tsslice
Read helpers in dependent packages accept RLocker, which a plain sync.Mutex
does not satisfy (it has no RLock/RUnlock). This forces callers that need
shared read access to supply an sync.RWMutex-like type at compile time, rather
than serializing every read behind an exclusive lock. A sync.RWMutex satisfies
both Locker and RLocker, so the same lock instance can drive read and write
helpers.
These interfaces only describe the locking contract; they do not enforce it. All access to the protected data must funnel through the helper functions using the same lock instance, otherwise concurrent reads and writes are not safe.
When To Use
- You are writing a goroutine-safe type and want the caller to choose sync.Mutex or sync.RWMutex.
- Read-heavy code should be able to declare that it only needs a shared lock.
Example
c := &counter{
mux: &sync.Mutex{},
values: make(map[string]int),
}
var wg sync.WaitGroup
for range 100 {
wg.Go(func() {
c.inc("hits")
})
}
wg.Wait()
fmt.Println(c.values["hits"])
// Output:
// 100
Full source is in example_threadsafe_test.go. More runnable examples are on pkg.go.dev.
Dependencies
This package reaches no external module: it uses only the Go standard library.