首页 > 解决方案 > 在多线程中记录冲突

问题描述

我想用这个简单的代码记录多线程中的冲突

    public T DataRef
    {
        get
        {
            Collisions.DetectAndSaveCollision(typeof(T).ToString(), Sync);
            lock (Sync)
            {
                return _tData;
            }
        }
        set
        {
            IsInitialized = true;
            Collisions.DetectAndSaveCollision(typeof(T).ToString(), Sync);
            lock (Sync)
            {
                _tData = value;
            }
        }
    }

这是在碰撞列表中添加元素的方法

    public static void DetectAndSaveCollision(string value, object lockObject)
    {
        var acquired = false;
        try
        {
            acquired = Monitor.TryEnter(lockObject);
        }
        finally
        {
            if (acquired)
            {
                Monitor.Exit(lockObject);
            }
            else
            {
                lock (lockObject)
                {
                    CollisionCollection.Add(Thread.CurrentThread, value);
                }
            }
        }
    }

但我不确定它是否没有死锁

标签: c#.netmultithreadinglocking

解决方案


这是无死锁的,因为最多同时获得一个锁。

正如 Lasse 在评论中指出的那样,这里存在竞争条件,因为您Sync连续两次获得锁。所以数据不会很准确。如果近似数据对您来说足够了,那么这很好。

您可以通过在获得锁时不立即释放锁来修复比赛。像这样的东西:

var acquiredImmediately = Monitor.TryEnter(...); //test lock

if (!acquiredImmediately) {
    Log(...);
    Monitor.Enter(...); //retry by blocking
}

CriticalRegion();

Monitor.Exit();

finally当然需要保护。


推荐阅读