線程同步問題

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;             }         }     } }  

相關文章
相關標籤/搜索