线程同步问题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;ide

namespace 线程同步问题
{
    class Program
    {
        /// <summary>
        /// 首先声明一个事件类,其实是这样的用这个类的实例对象去控制两个线程之间的同步。原理是这样的这个对象有两种状态,若是这个对象是终止状态和非终止状态。若是这个对象是终止状态,
        /// 那这个对象调用其等待状态时候,调用waitone时阻塞被当即释放,也就是没有起到阻塞的做用;而后由于这个对象模式是autoReset;因此这个对象会被置为非终止状态。
        /// 因此此次再调用阻塞方法,那就会阻塞这个线程。
        /// 疑问:
        /// autoReset是说被释放一次后会根据模式决定是不是在非终止状态。其实是对释放后状态的判断。
        /// waitone:若是是被置为终止状态,线程被永远执行,执行开始后被置为非终止状态。等待下一次被阻塞。
        /// 疑问:什么状况下会阻塞线程。什么状况下会释放线程。
        /// 阻塞线程,非终止状态下,调用waitone等一下的方法,这个是在同一个线程内的。线程终止
        ///          终止状态下,调用waitone等一下的方法,线程不终止继续执行。
        /// 三个方法:waitone(),set(),reset()
        /// waitone()是阻塞这个线程
        /// set()是释放被阻塞的线程
        /// reset()是设置这个类是非终止状态。
        /// 终止状态:应该叫可否使用状态;若是是true就是不能使用;就是终止状态;若是是false就是能使用,非终止状态。
        /// 只有在非终止状态下,才能使用这个waitone才有做用。set才有做用。waitone(),set()是使其设置成终止状态,就是不阻塞状态,只有reset()才能起做用。
        /// 并且在阻塞被释放时,触发是否把状态设置回非终止状态的动做。
        /// 实质:这个实质应该是一个待条件的循环。若是是终止状态,调用waitone()线程不阻塞,若是是非终止状态,调用waitone()是阻塞,
        ///
        ///
        ///
        /// 具体使用流程:
        /// 调用waitone()阻塞:看是否能阻塞,能就阻塞,不能就不阻塞。再根据是否自动恢复为可以使用决定事件状态。
        /// 能阻塞,调用set中止阻塞线程,并设置阻塞不可以使用。再根据是否自动恢复为可以使用决定事件状态。
        /// 不能阻塞,要手动设置为非终止状态,方法是:reset().
        ///
        ///
        /// 另外一线程决定此线程是否阻塞。set()是另外一线程处理的
        ///
        ///
        /// 固然也能够在本线程内处理。
        ///
        ///
        /// </summary>
        static EventWaitHandle eHandle;测试

        static void UnblockDemo()
        {
            Console.WriteLine("测试EventWaitHandle的初始终止状态");
            eHandle = new EventWaitHandle(true, EventResetMode.AutoReset);//eHandle初始为终止状态,模式为AutoReset
            eHandle.WaitOne();//因为EventWaitHandle对象eHandle初始状态为终止状态,因此这里第一次调用WaitOne时阻塞被当即释放,又因为eHandle为AutoReset模式,因此以后eHandle会被置为非终止状态
            Console.WriteLine("线程未被阻塞");
            eHandle.WaitOne();//因为此时eHandle已经为非终止状态,因此此时调用WaitOne线程会被阻塞
            Console.WriteLine("线程被阻塞");
        }spa

        static void BlockDemo()
        {
            Console.WriteLine("测试EventWaitHandle的初始非终止状态");
            eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
            eHandle.WaitOne();//因为EventWaitHandle对象eHandle初始状态为非终止状态,因此这里第一次调用WaitOne时,线程就被组塞了;autoReset指是否被回复为非终止状态。
            Console.WriteLine("线程被阻塞");
        }线程

        static void AutoResetDemo()
        {
            Console.WriteLine("测试EventWaitHandle的AutoReset模式");
            eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
            ///启动另外一个线程
            //ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
            //{
            //    //启动另外一个线程,每隔3秒钟调用一次eHandle.Set方法,为主线程释放一次阻塞,一共释放3次
            //    for (int i = 0; i < 3; i++)
            //    {
            //        Thread.Sleep(3000);
            //        eHandle.Set();//因为eHandle处于AutoReset模式,因此每次使用Set将eHandle置为终止状态后,待被WaitOne阻塞的线程被释放后,eHandle又会被自动置回非终止状态
            //    }
            //}), null);
            ThreadPool.QueueUserWorkItem(new WaitCallback(
                (object o) =>
                {对象

                    //启动另外一个线程,每隔3秒钟调用一次eHandle.Set方法,为主线程释放一次阻塞,一共释放3次
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(3000);
                        eHandle.Set();//因为eHandle处于AutoReset模式,因此每次使用Set将eHandle置为终止状态后,待被WaitOne阻塞的线程被释放后,eHandle又会被自动置回非终止状态
                    }事件

 

                }同步

                ),null);
            eHandle.WaitOne();//线程第一次被WaitOne阻塞
            Console.WriteLine("第一次WaitOne调用阻塞已被释放,3秒后第二次WaitOne调用的阻塞会被释放");
            eHandle.WaitOne();//线程第二次被WaitOne阻塞
            Console.WriteLine("第二次WaitOne调用阻塞已被释放,3秒后第三次WaitOne调用的阻塞会被释放");
            eHandle.WaitOne();//线程第三次被WaitOne阻塞
            Console.WriteLine("第三次WaitOne调用阻塞已被释放,全部WaitOne调用的阻塞都已被释放");
        }string

        static void ManualResetDemo()
        {
            Console.WriteLine("测试EventWaitHandle的ManualReset模式");
            eHandle = new EventWaitHandle(false, EventResetMode.ManualReset);//eHandle初始为非终止状态,模式为ManualReset
            ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
            {
                //启动另外一线程,3秒后调用一次eHandle.Set方法,为主线程释放WaitOne阻塞
                Thread.Sleep(3000);
                eHandle.Set();//因为eHandle处于ManualReset模式,因此一旦使用Set将eHandle置为终止状态后,在eHandle的Reset被调用前eHandle会一直处于终止状态,在eHandle调用Reset前,全部被WaitOne阻塞的线程会当即获得释放
            }), null);it

            eHandle.WaitOne();//线程第一次被WaitOne阻塞
            Console.WriteLine("第一次WaitOne调用阻塞已被释放,第二次WaitOne调用的阻塞会被当即释放");
            eHandle.WaitOne();//线程第二次被WaitOne阻塞
            Console.WriteLine("第二次WaitOne调用阻塞已被释放,第三次WaitOne调用的阻塞会被当即释放");
            eHandle.WaitOne();//线程第三次被WaitOne阻塞
            Console.WriteLine("第三次WaitOne调用阻塞已被释放,全部WaitOne调用的阻塞都已被释放");io

            eHandle.Reset();//调用eHandle的Reset方法,将eHandle手动置回非终止状态,以后再调用WaitOne方法就会被阻塞了
            eHandle.WaitOne();//线程第四次被WaitOne阻塞
            Console.WriteLine("第四次WaitOne调用阻塞已被释放");
        }

        static void Main(string[] args)         {             Console.Write("你想测试哪个方法1=UnblockDemo,2=BlockDemo,3=AutoResetDemo,4=ManualResetDemo:");             switch (Console.ReadLine())             {                 case "1":                     UnblockDemo();                     break;                 case "2":                     BlockDemo();                     break;                 case "3":                     AutoResetDemo();                     break;                 case "4":                     ManualResetDemo();                     break;                 default:                     break;             }         }     } }  

相关文章
相关标签/搜索