.NET使用AutoResetEvent实现多线程打印奇偶数

AutoResetEvent 类 (System.Threading) | Microsoft Docs

定义

表示线程同步事件在一个等待线程释放后收到信号时自动重置。 此类不能被继承。

注解

线程通过调用 AutoResetEvent 等待信号 如果 AutoResetEvent 处于非终止状态,则线程将会阻塞,直到调用 AutoResetEvent 调用 Set 方法向阻塞线程发送可用信号, AutoResetEvent 以释放等待线程。

AutoResetEvent 在一个等待线程释放之前保持终止状态,然后自动返回到非终止状态。 如果没有等待的线程,状态将保持无限期通知。

如果线程 WaitOne AutoResetEvent 在处于终止状态时调用,则线程不会阻塞。 AutoResetEvent立即释放该线程并返回到非终止状态。

AutoResetEvent 可以通过将布尔值传递到构造函数来控制的初始状态:

若要将初始状态设置为终止,则为 true;若要将初始状态设置为非终止,则为 false

AutoResetEvent 还可与 static WaitAll 和方法一起使用 WaitAny

从 .NET Framework 版本2.0 开始, AutoResetEvent 派生自新 EventWaitHandle 类。 AutoResetEvent在功能上等效于 EventWaitHandle 使用创建的 EventResetMode.AutoReset

示例

功能:

定义两个线程,从1打印到100,一个线程打印奇数,一个线程打印偶数。

实现:

奇数线程,设置奇数锁等待WiatOne,打印完成后,向偶数锁发送Set

偶数线程,设置偶数锁等待WiatOne,打印完成后,向奇数锁发送Set

调用AutoResetEventSet方法使奇数线程先执行

代码:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        //定义两个信号锁
        public static AutoResetEvent even = new AutoResetEvent(false);
        public static AutoResetEvent odd = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            Thread even_thread = new Thread(() =>
            {
                for (int i = 1; i <= 100; i++)
                {
                    if (i % 2 == 0)
                    {
                        even.WaitOne();//设置偶数线程等待
                        Console.WriteLine($"{Thread.CurrentThread.Name} {i}");
                        odd.Set();//向奇数线程发送可用信号
                    }
                }
            });
            even_thread.Name = $"Thread_even";
            even_thread.Start();

            Thread odd_thread = new Thread(() =>
            {
                for (int i = 1; i <= 100; i++)
                {
                    if (i % 2 != 0)
                    {
                        odd.WaitOne();//设置奇数线程等地
                        Console.WriteLine($"{Thread.CurrentThread.Name} {i}");
                        even.Set();//向偶数线程发送可用信号
                    }
                }
            });
            odd_thread.Name = $"Thread_odd";
            odd_thread.Start();
            odd.Set();//奇数线程先运行
            Console.ReadKey();
            Console.WriteLine("End...");
        }

    }
}

输出结果:

输出结果

posted @ 2020-11-30 11:49  刘大大。  阅读(200)  评论(0编辑  收藏  举报