Phase 13 of 30 · Topic 13.5

Concurrent Collections: `ConcurrentDictionary` vs `Lock` (.NET 9)

1Concept

`ConcurrentDictionary<TKey, TValue>` provides lock-striped thread-safe operations. .NET 9 introduces the dedicated `System.Threading.Lock` object, which achieves higher performance than `Monitor` (`lock(object)`).

2Architecture Diagram

Legacy: lock(object) ──> Enters CLR Monitor syncblock
.NET 9: lock(new System.Threading.Lock()) ──> Modern fast-path lightweight lock!

3Code Example

C# 13 & .NET 9
using System;
using System.Collections.Concurrent;
using System.Threading;

public class ConcurrencyCollectionDemo
{
    public static void Main()
    {
        var concurrentCache = new ConcurrentDictionary<string, int>();

        // GetOrAdd is atomic and lock-striped
        int count = concurrentCache.GetOrAdd("active_sessions", key => 1);
        Console.WriteLine($"Session Count: {count}");

        // .NET 9 Dedicated Lock Primitive
        System.Threading.Lock modernLock = new();
        lock (modernLock)
        {
            Console.WriteLine("Executing critical section inside .NET 9 Lock primitive.");
        }
    }
}

4Expected Output

Session Count: 1
Executing critical section inside .NET 9 Lock primitive.

5Key Takeaways

  • Use `ConcurrentDictionary` for shared multi-threaded read/write caches.
  • In .NET 9, use `System.Threading.Lock` instead of dummy `object _lock = new()` instances.
  • Be careful with factories in `GetOrAdd`: factory delegates may execute multiple times under race conditions.