Sobes.tech
Middle+

Kako implementirati Dictionary bez korišćenja ConcurrentDictionary?

sobes.tech АИ

Одговор од АИ

Za implementaciju thread-safe Dictionary bez korišćenja ConcurrentDictionary, mogu se primeniti sinhronizacijski primitivni iz prostora imena System.Threading.

Glavni pristupi:

  1. Zaključavanje celog rečnika (lock): Obuhvatiti sve operacije čitanja i pisanja u blok lock koristeći isti objekat za sinhronizaciju.

    // Objekat za sinhronizaciju pristupa rečniku
    private readonly object _lockObject = new object();
    private readonly Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
    
    public void AddOrUpdate(TKey key, TValue value)
    {
        lock (_lockObject)
        {
            if (_dictionary.ContainsKey(key))
            {
                _dictionary[key] = value;
            }
            else
            {
                _dictionary.Add(key, value);
            }
        }
    }
    
    public bool TryGetValue(TKey key, out TValue value)
    {
        lock (_lockObject)
        {
            return _dictionary.TryGetValue(key, out value);
        }
    }
    
    public bool TryRemove(TKey key, out TValue value)
    {
        lock (_lockObject)
        {
            if (_dictionary.TryGetValue(key, out value))
            {
                _dictionary.Remove(key);
                return true;
            }
            return false;
        }
    }
    

    Prednosti: Jednostavna implementacija. Nedostaci: Niska performansa pri visokim konkurencijama, jer je pristup celom rečniku blokiran čak i pri operacijama čitanja.

  2. Korišćenje ReaderWriterLockSlim: Omogućava razdvajanje zaključavanja za operacije čitanja i pisanja. Više niti može istovremeno čitati, ali samo jedna može pisati.

    private readonly ReaderWriterLockSlim _lockSlim = new ReaderWriterLockSlim();
    private readonly Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
    
    public void AddOrUpdate(TKey key, TValue value)
    {
        _lockSlim.EnterWriteLock();
        try
        {
            if (_dictionary.ContainsKey(key))
            {
                _dictionary[key] = value;
            }
            else
            {
                _dictionary.Add(key, value);
            }
        }
        finally
        {
            _lockSlim.ExitWriteLock();
        }
    }
    
    public bool TryGetValue(TKey key, out TValue value)
    {
        _lockSlim.EnterReadLock();
        try
        {
            return _dictionary.TryGetValue(key, out value);
        }
        finally
        {
            _lockSlim.ExitReadLock();
        }
    }
    
    public bool TryRemove(TKey key, out TValue value)
    {
        _lockSlim.EnterWriteLock();
        try
        {
            if (_dictionary.TryGetValue(key, out value))
            {
                _dictionary.Remove(key);
                return true;
            }
            return false;
        }
        finally
        {
            _lockSlim.ExitWriteLock();
        }
    }
    

    Prednosti: Bolja performansa u poređenju sa lock pri intenzivnim operacijama čitanja. Nedostaci: Složenija implementacija u poređenju sa jednostavnim lock.

Izbor između ovih pristupa zavisi od specifičnosti korišćenja rečnika, odnosa operacija čitanja i pisanja, i zahteva za performansama. ReaderWriterLockSlim je obično preferiran pri čestim operacijama čitanja.