今天我遇到了这段代码
internal object UpdatePracownik(object employee)
{
lock (employee)
{
// rest of the code
}
return employee;
}
我想知道这是否是锁定访问功能的有效解决方案?
使用属性
会更好[MethodImpl(MethodImplOptions.Synchronized)]
而不是这种锁?
答案 0 :(得分:1)
这取决于。如果所有线程都通过传递相同的全局可见对象作为参数来调用此方法,那么它们将看到相同的锁并且没有问题。
相反,如果每个线程都通过传递自己的对象来调用此方法,那么锁定是无用的,因为它们都看到不同的锁。我们必须知道调用该方法的上下文,看它是否安全。
使用您提出的同步方法,可以将整个方法体包装在lock(this)
语句中,如:
internal object UpdatePracownik(object employee)
{
lock (this)
{
// code
}
}
这将保证多线程执行的原子性,但可能因为你的目的而过于粗糙,通常是不可取的。
答案 1 :(得分:1)
使用MethodImpl
属性同步方法相当于锁定特定于该方法的对象。
这意味着一次只有一个线程可以运行该方法,但只要它们不使用相同的数据,就可能不需要排除其他线程。
这也意味着该方法本身是同步的,但您可能也希望使用相同的标识符来锁定其他方法。例如,您可能希望方法DeletePracownik
与UpdatePracownik
同步,以便在更新时无法删除它。
答案 2 :(得分:0)
锁定员工实例是一个坏主意,因为锁定'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();
}
}