今天遇到了这段代码
internal object UpdatePracownik(object employee)
{
lock (employee)
{
// rest of the code
}
return employee;
}
我想知道这是否是锁定功能访问的有效解决方案?
使用属性不会更好
[MethodImpl(MethodImplOptions.Synchronized)]
而不是这种锁?
今天遇到了这段代码
internal object UpdatePracownik(object employee)
{
lock (employee)
{
// rest of the code
}
return employee;
}
我想知道这是否是锁定功能访问的有效解决方案?
使用属性不会更好
[MethodImpl(MethodImplOptions.Synchronized)]
而不是这种锁?
这要看情况。如果所有线程通过传递相同的全局可见对象作为参数来调用此方法,那么它们都将看到相同的锁并且不会有任何问题。
相反,如果每个线程都通过传递自己的对象来调用此方法,那么锁定是无用的,因为它们都看到不同的锁。我们必须知道调用该方法的上下文,看看这是否安全。
使用您提出的同步方法可以将整个方法体包装在lock(this)
如下语句中:
internal object UpdatePracownik(object employee)
{
lock (this)
{
// code
}
}
这将保证多线程执行的原子性,但对于您的目的可能过于粗略,通常不建议使用。
使用MethodImpl
属性来同步方法等同于锁定特定于方法的对象。
这意味着一次只有一个线程可以运行该方法,但可能不需要排除其他线程,只要它们不使用相同的数据。
这也意味着该方法本身是同步的,但您可能也希望使用相同的标识符锁定其他方法。例如,您可能希望该方法DeletePracownik
与 同步UpdatePracownik
,这样您就不能在更新一个对象时删除它。
锁定员工实例是个坏主意,锁定“this”也是出于同样的原因:您无法控制的代码也可能锁定这些实例并导致死锁(blogs.msdn.com/b/bclteam/archive/ 2004/01/20/60719.aspx)。最好使用私有成员:
private readonly object _lock = new object();
...
lock (_lock)
{
..
}
此外,您应该熟悉ReaderWriterLockSlim。通常您可能希望允许并发访问某些功能,除非正在进行写入操作:
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
public void ReadOp()
{
_rwLock.EnterReadLock(); //only blocks if write lock held
try
{
//do read op
}
finally
{
_rwLock.ExitReadLock();
}
}
public void WriteOp()
{
_rwLock.EnterWriteLock(); //blocks until no read or write locks held
try
{
//do write op
}
finally
{
_rwLock.ExitWriteLock();
}
}