C# 使用AutoResetEvent进行线程同步

时间:2021-01-22 05:14:09

AutoResetEvent 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。

线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。

调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。

AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程.

 static AutoResetEvent a = new AutoResetEvent(false);//WaitOne会阻止false,但是不会阻止true,内部自动reset了

        public static void MainTest()
{
Thread[] ths = new Thread[];
for (int i = ; i < ; i++)
{
ths[i] = new Thread(increaseCount);
ths[i].Start();
} a.Set();//如果是非终止状态,一定要在这里Set下,不然线程一直处于等待状态
System.Console.ReadKey();
} static void increaseCount()
{
a.WaitOne();//当得到信号后,内部又将状态设置为非终止状态,相当于独占了。 Random ran = new Random();
Thread.Sleep(ran.Next(, ));
int beginNum = SharedResource1.Count;
System.Console.WriteLine("线程 {0} 读到的起始值为 {1} ", Thread.CurrentThread.ManagedThreadId, beginNum);
for (int i = ; i < ; i++)
{
beginNum++;
} SharedResource1.Count = beginNum;
System.Console.WriteLine("线程 {0} 结束,SharedResource.Count={1}", Thread.CurrentThread.ManagedThreadId, SharedResource1.Count);
a.Set();
}
} class SharedResource1
{
public static int Count = ;
}