Run-once initialization¶
Category: Synchronization · Status: stub · Lessons: chapter 04, Waiting for each other (planned)
One line: Running an initializer exactly once however many threads ask for it at the same moment, and handing all of them the same result.
Also called: lazy initialization, double-checked locking, sync.Once, OnceLock, call_once.
How it connects¶
flowchart LR
n_once_initialization["Run-once initialization"]
n_synchronization["Synchronization"]
n_once_initialization -->|is a| n_synchronization
classDef center stroke-width:3px
class n_once_initialization center
classDef outside stroke-dasharray: 4 3
class n_synchronization outside
- Is a kind of: Synchronization
In each language¶
| Rust | Once ↗, OnceLock ↗, and LazyLock ↗, a value initialized on first access that can live in a static |
| Go | sync.Once ↗ performs exactly one action; sync.OnceValue ↗ (Go 1.21) returns a function that calls f only once |
| C | call_once ↗ (C11) calls the function exactly once, even from several threads |
| C++ | std::call_once ↗, and a static local variable ↗ is initialized exactly once even when threads reach it concurrently |
| Java | Class initialization runs under a unique per-class initialization lock (JLS §12.4.2 ↗) |
| Python | Not functools.cached_property ↗: since 3.12 it takes no lock, so synchronize the getter yourself |
| C# | Lazy<T> ↗ with LazyThreadSafetyMode.ExecutionAndPublication: the initialization is thread-safe, but the object it creates is not protected afterwards |
| Kotlin | by lazy ↗ is synchronized by default: the value is computed in one thread and all threads see it |
| The operating system | POSIX pthread_once ↗: later calls with the same once_control do not call the routine again |
Where to read more¶
- In a sibling library: Go:
sync.Onceruns exactly once ↗ - In the books: Programming with POSIX Threads, David R. Butenhof — ch. 5, 'Advanced Threaded Programming' → 'One-time initialization'
- In the books: Multi-Threaded Programming in C++, Mark Walmsley — ch. 7, 'Keys' → 'One-Time Initialization'
- In the books: The Go Programming Language, Alan A. A. Donovan, Brian W. Kernighan — ch. 9, 'Concurrency with Shared Variables' → 'Lazy Initialization: sync.Once'
- In the books: Effective Java, Joshua Bloch — ch. 11, 'Concurrency' → 'Item 83: Use lazy initialization judiciously'
- In the books: C# 10 in a Nutshell, Joseph Albahari — ch. 21, 'Advanced Threading' → 'Lazy Initialization'
- In the books: The Go Programming Language Phrasebook, David Chisnall — ch. 9, 'Goroutines' → 'Performing Thread-Safe Initialization'
- Reference: Wikipedia: Double-checked locking ↗