c# - 线程 Thread AutoResetEvent 与 ManualResetEvent

using System;
using System.IO;
using System.Text;
using System.Threading;

namespace ThreadingDemo
{
    /// <summary>
    /// AutoResetEvent及ManualResetEvent: 主要目的是使线程同步执行:
    /// 1. 线程1:在当前线程方法中调用_waitHandle1.WaitOne(), 使线程1阻塞。(_waitHandle1: 一个AutoResetEvent对象或一个ManualResetEvent对象)
    /// 2. 在其它线程(例如主线程)中调用_waitHandle1.Set(), 恢复线程1的执行, 方法从_waitHandle1.WaitOne()处向后执行。
    /// 3. AutoResetEvent与ManualResetEvent的主要区别是: 
    ///     a. AutoResetEvent.Set()每次只能恢复一个WaitOne()
    ///     b. ManualResetEvent.Set()一次恢复所有的WaitOne(), 请参见ManualResetEvent示例.
    /// </summary>
    class Program
    {
        static EventWaitHandle _waitHandle1 = new AutoResetEvent(false);
        static EventWaitHandle _waitHandle2 = new AutoResetEvent(false);

        static EventWaitHandle _waitHandleManual = new ManualResetEvent(false);
        static EventWaitHandle _waitHandleAuto = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            // 1. AutoResetEvent示例1
            new Thread(WaiterAuto).Start();
            while (true)
            {
                Console.WriteLine("Press <Enter> to release threads.");
                Console.ReadLine();
                _waitHandleAuto.Set();
            }

            // 2. ManualResetEvent示例
            /*
            new Thread(WaiterManual).Start();
            while (true)
            {
                Console.WriteLine("Press <Enter> to release threads.");
                Console.ReadLine();
                _waitHandleManual.Set();
            }
            */

            // 3. 2 threads suspend and release each other.
            /*
            new Thread(Waiter1).Start();
            new Thread(Waiter2).Start();
            */

            // 4. AutoResetEvent示例2: 一次Set()释放一个线程
            /*
            new Thread(Print).Start();
            new Thread(Print).Start();
            new Thread(Print).Start();
            while (true)
            {
                Console.WriteLine("Press <Enter> to release one thread.");
                Console.ReadLine();
                // 一次仅释放一个线程
                _waitHandleAuto.Set();
            }
            */
        }

        static void Print()
        {
            while (true)
            {
                string line = "Hello from Thread:" + Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine(line);
                Thread.Sleep(1000);
                _waitHandleAuto.WaitOne();
            }
        }

        static void WaiterAuto()
        {
            while (true)
            {
                // 向文本文件中写内容
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 第一次等待
                _waitHandleAuto.WaitOne();

                // 向文本文件中写内容
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 3; i < 6; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 第二次等待
                _waitHandleAuto.WaitOne();
            }
        }

        static void WaiterManual()
        {
            while (true)
            {
                // 向文本文件中写内容
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 第一次等待
                _waitHandleManual.WaitOne();

                // 向文本文件中写内容
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 3; i < 6; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 第二次等待
                _waitHandleManual.WaitOne();
            }
        }

        static void Waiter1()
        {
            while (true)
            {
                // 阻塞线程1(Waiter1)
                _waitHandle1.WaitOne();
               
                // 向文本文件中写内容
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 释放线程2(Waiter2)
                _waitHandle2.Set();
            }
        }

        static void Waiter2()
        {
            while (true)
            {
                // 向文本文件中写内容。
                using (StreamWriter sw = new StreamWriter("output.txt", false, Encoding.UTF8))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        string line = "Thread:" + Thread.CurrentThread.ManagedThreadId + " called =>" + (i + 1);
                        Console.WriteLine(line);
                        sw.WriteLine(line);
                        Thread.Sleep(500);
                    }
                }
                // 释放线程1(Waiter1)
                _waitHandle1.Set();
                // 阻塞线程2(Waiter2)
                _waitHandle2.WaitOne();
            }
        }
    }
}
发布了130 篇原创文章 · 获赞 20 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/yuxuac/article/details/96917106
今日推荐