2

今天我碰到这段代码锁定功能体功能参数对象

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

    return employee; 
} 

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

岂不是更好地使用属性

[MethodImpl(MethodImplOptions.Synchronized)] 

代替这种锁的?

+0

这可能有助于描述您尝试实现什么功能?你是否打算锁定'employee'对象的特定实例,或锁定所有'UpdatePracwnik'方法的用法? – 2012-01-18 14:21:51

回答

1

嗯,这取决于。如果所有线程都通过传递与参数相同的全局可见对象来调用此方法,那么它们将看到相同的锁,并且不会有问题。

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

使用由您提出的同步方法使得整个方法体被包裹在一个lock(this)声明,如:

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

这将确保由多个线程执行的原子性,但可能太粗晶为您的目的通常不可取。

+1

我会走得更远,并说'锁定'这是一个很大的不,不是(http://blogs.msdn.com/b/bclteam/archive/2004/01/20/60719.aspx)。问题在于,不受控制的代码也可能会锁定实例并可能导致死锁。私有成员private只读_lock = new object();是优选的 – 2012-01-18 13:22:21

1

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

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

这也意味着该方法本身是同步的,但您也可能想要使用相同的标识符锁定其他方法。例如,您可能希望方法DeletePracownikUpdatePracownik一起同步,以便在更新时不能删除一个对象。

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(); 
    } 
}