Learn different ways to protect shared state.
Create:
LockCounterMonitorCounterInterlockedCounter- optional
ReaderWriterLockCounter
Use a private lock object.
private readonly object _sync = new();Never expose the lock object publicly.
Rewrite the same logic using:
Monitor.Enter(_sync);
Monitor.Exit(_sync);Use try/finally.
Use:
Interlocked.Increment(ref _value);Use this for simple atomic numeric operations.
Use this only to explore read-heavy scenarios.
For every implementation:
- single increment
- many increments
- concurrent increments
Measure:
- 1,000 increments
- 100,000 increments
- 1,000,000 increments
- concurrent increments
Pros:
- Simple.
- Protects complex invariants.
- Easy to understand.
Cons:
- Can block.
- Can cause deadlocks.
- Can suffer under high contention.
Pros:
- Very fast for simple operations.
- No explicit lock object.
- Low overhead.
Cons:
- Hard to compose.
- Not suitable for complex state transitions.
Use the simplest synchronization primitive that correctly protects the invariant.