2

今天遇到了这段代码

internal  object UpdatePracownik(object employee)
{  
    lock (employee)
    {
        // rest of the code 
    }

    return employee;
}

我想知道这是否是锁定功能访问的有效解决方案?

使用属性不会更好

[MethodImpl(MethodImplOptions.Synchronized)] 

而不是这种锁?

4

3 回答 3

1

这要看情况。如果所有线程通过传递相同的全局可见对象作为参数来调用此方法,那么它们都将看到相同的锁并且不会有任何问题。

相反,如果每个线程都通过传递自己的对象来调用此方法,那么锁定是无用的,因为它们都看到不同的锁。我们必须知道调用该方法的上下文,看看这是否安全。

使用您提出的同步方法可以将整个方法体包装在lock(this)如下语句中:

internal  object UpdatePracownik(object employee)
{
    lock (this)
    {
        // code        
    }
}

这将保证多线程执行的原子性,但对于您的目的可能过于粗略,通常不建议使用。

于 2012-01-18T12:55:03.700 回答
1

使用MethodImpl属性来同步方法等同于锁定特定于方法的对象。

这意味着一次只有一个线程可以运行该方法,但可能不需要排除其他线程,只要它们不使用相同的数据。

这也意味着该方法本身是同步的,但您可能也希望使用相同的标识符锁定其他方法。例如,您可能希望该方法DeletePracownik与 同步UpdatePracownik,这样您就不能在更新一个对象时删除它。

于 2012-01-18T12:58:53.603 回答
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();
     }
}
于 2012-01-18T13:28:55.857 回答