Lock和Monitor都是对被操作对象同步控制的方法
Lock 是 Monitor的简化版本,IL
callvirt ...Monitor.Enter(object)
...
leave.s
....
callvirt ...Monitor.Exit(object)
Lock 只能对引用对象加锁
Lock锁定区间内可以对锁定值修改而不发生运行时错误,通常也会采用此种修改方式。这种方式又有点类同于使用Monitor.Wait 取得资源,并对这个资源进行操作。
lock (lockObj)
{
lockObj = newObj;
}
Monitor 可以对值类型加锁,实际上是在调用Monitor.Enter时对值类型装箱了
Monitor在锁定区域内不能对被锁对象的值进行修改,运行时抱错“从不同步的代码块中调用了对象同步方法”
int lockInt = 0;
try
{
Monitor.Enter(lockInt);
lockInt = newValue;
}
catch
{
}
finally
{
Monitor.Exit(newValue);
}
Monitor 相对Lock有其他一些复杂功能
Monitor.TryEnter
//Try to add an element to the queue.
//Add the element to the queue only if the queue object is unlocked.
public bool AddElementWithoutWait(object qValue)
{
//Determine whether the queue is locked
if (!Monitor.TryEnter(m_inputQueue))
return false;
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);
return true;
}
//Try to add an element to the queue.
//Add the element to the queue only if during the specified time the queue object will be unlocked.
public bool WaitToAddElement(object qValue, int waitTime)
{
//Wait while the queue is locked.
if (!Monitor.TryEnter(m_inputQueue, waitTime))
return false;
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);
return true;
}
Monitor.Wait
Monitor.Pulse
Monitor.PulseAll
Monitor.Wait(m_smplQueue);
//Push one element.
m_smplQueue.Enqueue(counter);
//Release the waiting thread.
Monitor.Pulse(m_smplQueue);
Monitor.PulseAll(m_smplQueue);
Wait: 等待得到被锁对象,可以对被锁对象进行操作
Pulse: 释放当前锁定操作对象,下一个等待该对象的Wait将得到对象的使用权
PulseAll:释放当前锁定对象,所有正在等待该对象得Wait将同时得到释放(进入下一行代码,可以认为不在对该对象进行同步控制) |