锁定多个线程中的变量
我是C#的新手,我想询问我是否在MULTI THREADS(伪代码)中遇到这种情况:
public class ClassA { ClassB c = new ClassB(); public void someMethod() { c.myVar = 1; // Some other stuff c.myVar = 0; } } public class ClassB { internal int myVar; public void MethodA() { if(myVar = 1) myVar = 0; } }
如果someMethod()
和MethodA()
可以在单独的线程中处于活动状态,则MethodA()
可以将if语句计算为true; 但在设置myVar = 0
, someMethod()
设置myVar = 0
使得在MethodA()
中将myVar
设置为0是不正确的!
基本上,我如何锁定myVar
:
- 我可以在
myVar
的属性上lock{}
(set,get) - 我是否需要使用
Interlock
(虽然我还没有Interlock
经验)?
您应该创建一个允许锁定的私有对象:
private readonly object _locker = new object();
然后在你的属性get / set方法中,锁定它:
get { lock (_locker) { return this.myVar; } } set { lock (_locker) { this.myVar = value; } }
确保您的方法也使用锁:
public void MethodA() { lock(_locker) { if(myVar == 1) myVar = 0; } }
看起来您正在尝试实现某种信令机制。 您可以使用.NET库中提供的类之一(如ManualResetEvent
而不是自己编写。
我就是这样做的。
static readonly object _myVar_Lock = new object(); private int _myVar = 0; public int myVar { get { lock (_myVar_Lock) { return this._myVar; } } set { lock (_myVar_Lock) { this._myVar = value; } } }
我当然会重新考虑你的整体方法,但如果你想从不同的代码段同步访问ClassB
的成员那么你可以从ICollection
接口窃取一个不那么好的设计模式并暴露一个可以是的SyncRoot
属性用于获取与原始实例相同的锁。
public class ClassA { private ClassB c = new ClassB(); public void someMethod() { lock (c.SyncRoot) { c.MyVar = 1; // Some other stuff c.MyVar = 0; } } } public class ClassB { private object m_LockObject = new object(); private int m_MyVar; public object SyncRoot { get { return m_LockObject; } } public int MyVar { get { lock (SyncRoot) return m_MyVar; } set { lock (SyncRoot) m_MyVar = value; } } public void MethodA() { lock (SyncRoot) { if (m_MyVar == 1) m_Var = 0; } } }
您是否有多个线程共享同一个类实例而不是实现每个线程,以便它在其范围内获得自己的类实例?