AutoResetEvent作为C#中的锁替换
本文关键字:替换 作为 AutoResetEvent | 更新日期: 2023-09-27 18:19:44
我想知道:锁定只允许1个线程进入代码区域
等待句柄用于发出信号::
信令是指一个线程等待,直到收到来自另一个
所以我心想,这能用来换锁吗?
类似于:
Thread number 1 --please enter ( autoreset --> autlock)
dowork...
finish work...
set signal to invite the next thread
所以我写了这个:
/*1*/ static EventWaitHandle _waitHandle = new AutoResetEvent(true);
/*2*/
/*3*/ volatile int i = 0;
/*4*/ void Main()
/*5*/ {
/*6*/
/*7*/ for (int k = 0; k < 10; k++)
/*8*/ {
/*9*/ var g = i;
/*10*/ Interlocked.Increment(ref i);
/*11*/ new Thread(() = > DoWork(g)).Start();
/*12*/
/*13*/ }
/*14*/
/*15*/ Console.ReadLine();
/*16*/ }
/*17*/
/*18*/
/*19*/ void DoWork(object o)
/*20*/ {
/*21*/ _waitHandle.WaitOne();
/*22*/ Thread.Sleep(10);
/*23*/ Console.WriteLine((int) o + "Working...");
/*24*/ _waitHandle.Set();
/*25*/
/*26*/ }
如您所见:第21行、第24行是锁的替代品。
问题:
- 它是有效的替代品吗?(并不是说我将取代
lock
,而是想了解使用场景) - 我应该在什么时候使用每个
谢谢。
奇怪,但SO不包含关于_lock vs EventWaitHandle_
不要去那里。锁的一个重要特性是它提供公平性。换句话说,一个合理的保证,即争用锁的线程最终可以获得锁。Monitor类提供了这样的保证,由CLR中的等待队列实现。Mutex和Semaphore提供了这样的保证,并通过操作系统实现。
WaitHandles不提供此类保证。如果锁被争用,那么这是非常有害的,同一个线程可能会重复获取它,而其他线程可能会永远挨饿。
对锁使用适当的同步对象。等待手柄应仅用于发出信号。
这是可能的,但它比lock()慢得多,维护起来也困难得多。
顺便说一句,当使用Interlocked方法来维护一个值时,你永远不应该直接读取它
你的代码应该是这样的:
var g = Interlocked.Increment(ref i);
然后g将包含递增的值,而不是以前的某个值。