这就是编写线程安全IComparable的方法吗

本文关键字:IComparable 方法 安全 线程 | 更新日期: 2023-09-27 18:27:59

我有一个简单的类,我想让它线程安全。该类需要实现IComparer。我知道以线程安全的方式实现int CompareTo(T other)不是直接的。如果我不以正确的方式锁定,很容易出现死锁。我有三个问题:

  1. 这个代码线程安全吗?如果没有,我该如何修复
  2. 这个代码可以短一点吗?这看起来像是一个简单减法的大量代码
  3. 我甚至应该麻烦让int CompareTo(T other)线程安全吗?我应该要求调用者(通常是排序)锁定所有相关的BObjects吗

这是我的代码:

public class BObject : IComparable<BObject>
{
    //Each BObject has a unique object id
    private static int _bObjectId = 0;
    private static int GetNextId()
    {
        return System.Threading.Interlocked.Increment(ref BObject._bObjectId);
    }
    private object _locker = new object();
    private readonly int _id = BObject.GetNextId();
    //Some variable
    private int _sales;
    public int Sales
    {
        get
        {
            lock (this._locker)
                return this._sales;
        }
        set
        {
            lock (this._locker)
                this._sales = value;
        }
    }
    public int CompareTo(BObject other)
    {
        int result;
        //Can I simply do "if (this._id == other._id)"
        if (object.ReferenceEquals(this, other))
            result = 0;
        else
        {
            //get the BObject with the lower id
            BObject lower = this._id < other._id ? this : other;
            //get the BObject with the higher id
            BObject higher = this._id > other._id ? this : other;
            //lock the BObject with the lower id first
            lock (lower._locker)
            {
                //lock the BObject with the higher id last
                lock (higher._locker)
                {
                    //put object with lower Sales first
                    result = this.Sales - other.Sales;
                }
            }
        }
        return result;
    }
}

这就是编写线程安全IComparable的方法吗

在什么使用条件下,您希望这种比较与被比较值的突变同时发生?在这种情况下,什么行为应该是"正确的"?一旦定义了正确性的标准,就可以设计一种方法来实现线程安全性。

线程安全实际上是关于如何使用事物,以及这种使用如何跨线程边界进行交互。因此,例如,如果您正在对这些对象的列表进行排序,然后同时对集合进行突变,则您可能需要某种方法来防止在排序过程中发生突变。最糟糕的情况是,你可能会出现这样一种情况,即你以一种导致排序永远不会终止的方式对实例进行变异(这很难做到,但理论上是可能的。)简而言之,你需要更多地考虑如何使用这些实例的高级视角。最有可能的是,在实例访问器的级别上,这不是可以实现"线程安全"的东西。