我有一個簡單的類,我想使它線程安全。該類需要實現IComparer。我知道以線程安全的方式實施int CompareTo(T other)
並不是直截了當的。如果我不以正確的方式鎖定,那麼容易造成死鎖。我有三個問題:這是如何編寫線程安全IComparable?
- 此代碼是否線程安全?如果不是,我該如何解決?
- 此代碼可以縮短嗎?它看起來像一個簡單的減法很多代碼。
- 我應該甚至打擾
int CompareTo(T other)
線程安全嗎?我是否應該要求調用者(通常是排序)鎖定所有相關的BObject?
這裏是我的代碼:
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;
}
}
鎖定每個成員不會使您的代碼線程安全。 – SLaks
特別是,'int's已經是原子的;你根本不需要鎖。 – SLaks
使比較線程安全的最簡單方法:使您的類型不可變。 –