lock 和 Monitor (转载)

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将同时得到释放(进入下一行代码,可以认为不在对该对象进行同步控制)

posted @ 2014-04-02 14:01  liu0076  阅读(193)  评论(0编辑  收藏  举报