用函数参数对象锁定函数体
本文关键字:锁定 函数体 对象 参数 函数 | 更新日期: 2023-09-27 18:20:52
今天我遇到了一段代码
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();
}
}