最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中AutoResetEvent控制線程用法小結(jié)

 更新時間:2022年07月18日 15:25:42   作者:返回主頁大漠孤煙直,長河落日圓  
本文主要來自一道面試題,由于之前對AutoResetEvent的概念比較模糊,面試題題目很簡潔:兩個線程交替打印0~100的奇偶數(shù),你可以先動手試試,我主要是嘗試在一個方法里面完成這個任務(wù),需要的朋友可以參考下

本文主要來自一道面試題,由于之前對AutoResetEvent的概念比較模糊(即使已經(jīng)使用過了)。面試題題目很簡潔:兩個線程交替打印0~100的奇偶數(shù)。你可以先動手試試,我主要是嘗試在一個方法里面完成這個任務(wù)。

注: Suspend,Resume來控制線程已經(jīng)在.net framework2.0被淘汰了,原因就是掛起之后,但因為異常而沒有及時恢復(fù),如果占用資源會導(dǎo)致死鎖。

  • AutoResetEvent對象用來進行線程同步操作,AutoResetEvent類繼承waitHandle類。waitOne()方法就繼承來自waitHandle類。
  • AutoResetEvent對象有終止和非終止兩種狀態(tài),終止狀態(tài)是線程繼續(xù)執(zhí)行,非終止狀態(tài)使線程阻塞,可以調(diào)用set和reset方法使對象進入終止和非終止狀態(tài)。-》可以簡單理解如果AutoResetEvent對象是終止狀態(tài),就像不管別人了,任你撒野去(waitOne()得到的都是撒野信號)
  • AutoResetEvent顧名思義,其對象在調(diào)用一次set之后會自動調(diào)用一次reset,進入非終止狀態(tài)使調(diào)用了等待方法的線程進入阻塞狀態(tài)。-》可以簡單理解如果AutoResetEvent對象是非終止狀態(tài),就開始管理起別人來了,此時waitOne()得到的信號都是呆在原地不動信號。
  • waitHandle對象的waitone可以使當前線程進入阻塞狀態(tài),等待一個信號。直到當前 waitHandle對象收到信號,才會繼續(xù)執(zhí)行。
  • set可以發(fā)送一個信號,允許一個調(diào)用waitone而等待線程繼續(xù)執(zhí)行。 ManulResetEvent的set方法可以允許多個。但是要手動關(guān)閉,即調(diào)用reset();
  • reset可以使因為調(diào)用waitone() 而等待線程都進入阻塞狀態(tài)。

AutoResetEvent主要方法及實踐

  • AutoResetEvent(bool initialState):構(gòu)造函數(shù),用一個指示是否將初始狀態(tài)設(shè)置為終止的布爾值初始化該類的新實例。 false:無信號,子線程的WaitOne方法不會被自動調(diào)用 true:有信號,子線程的WaitOne方法會被自動調(diào)用
  • Reset ():將事件狀態(tài)設(shè)置為非終止狀態(tài),導(dǎo)致線程阻止;如果該操作成功,則返回true;否則,返回false。
  • Set ():將事件狀態(tài)設(shè)置為終止狀態(tài),允許一個或多個等待線程繼續(xù);如果該操作成功,則返回true;否則,返回false。
  • WaitOne(): 阻止當前線程,直到收到信號。
  • WaitOne(TimeSpan, Boolean) :阻止當前線程,直到當前實例收到信號,使用 TimeSpan 度量時間間隔并指定是否在等待之前退出同步域。

有了上面的解釋,開始展示代碼(經(jīng)過多次優(yōu)化)

 //若要將初始狀態(tài)設(shè)置為終止,則為 true;若要將初始狀態(tài)設(shè)置為非終止,則為 false
        static AutoResetEvent oddResetEvent = new AutoResetEvent(false);
        static AutoResetEvent evenResetEvent = new AutoResetEvent(false);
        static int i = 0;
        static void Main(string[] args)
        {
            //ThreadStart是個委托
            Thread thread1 = new Thread(new ThreadStart(show));
            thread1.Name = "偶數(shù)線程";
            Thread thread2 = new Thread(new ThreadStart(show));
            thread2.Name = "奇數(shù)線程";
            thread1.Start();
           Thread.Sleep(2); //保證偶數(shù)線程先運行。
            thread2.Start();
            Console.Read();

        }
        public static void show()
        {
             while (i <= 100)
            {
                int num = i % 2;
                if (num == 0)
                {
                    Console.WriteLine("{0}:{1} {2}  ", Thread.CurrentThread.Name, i++, "evenResetEvent");
                    if(i!=1) evenResetEvent.Set(); 
                    oddResetEvent.WaitOne(); //當前線程阻塞
                   
                }
               else
                {  
                    Console.WriteLine("{0}:{1} {2} ", Thread.CurrentThread.Name, i++, "oddResetEvent");
                    //如果此時AutoResetEvent 為非終止狀態(tài),則線程會被阻止,并等待當前控制資源的線程通過調(diào)用 Set 來通知資源可用。否則不會被阻止
                     oddResetEvent.Set();
                    evenResetEvent.WaitOne();
                }
            }
        }

結(jié)果如下圖所示:

注意點:
不要有一點點點點多余的evenResetEvent.Set(),他會讓后續(xù)的 evenResetEvent.WaitOne();失效.

第二種方法Semaphore

此外,我們利用信號量也可以實現(xiàn),信號量是一種內(nèi)核模式鎖,對性能要求比較高,特殊情況下才考慮使用,而且要避免在內(nèi)核模式和用戶模式下頻繁相互切換線程。代碼如下:

 private static readonly int MaxSize = 1;
        private static int i = 0;
        static Semaphore oddSemaphore = new Semaphore(0, MaxSize);
        static Semaphore evenSemaphore = new Semaphore(0, MaxSize);

        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            //ThreadStart是個委托
            Thread thread1 = new Thread(new ThreadStart(show));
            thread1.Name = "偶數(shù)線程";
            Thread thread2 = new Thread(new ThreadStart(show));
            thread2.Name = "奇數(shù)線程";
            thread1.Start();
            thread2.Start();
            thread1.Join();
            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds);
            Console.Read();
        }

        private static void show()
        {
            if(i==1) evenSemaphore.WaitOne();
            while (i <= 100)
            {
                int num = i % 2;
                if (num == 0)
                {
                    Console.WriteLine("{0}:{1}  {2}    ", Thread.CurrentThread.Name, i++, Thread.CurrentThread.ManagedThreadId);
                    evenSemaphore.Release();
                    oddSemaphore.WaitOne(); //當前線程阻塞
                }
                else
                {
                    Console.WriteLine("{0}:{1}  {2}    ", Thread.CurrentThread.Name, i++, Thread.CurrentThread.ManagedThreadId);
                    //釋放一個偶數(shù)信號空位出來;
                    oddSemaphore.Release();
                    evenSemaphore.WaitOne(); //當前線程阻塞
                    //此時已經(jīng)消耗了一個奇數(shù)信號空位
                }
            }
        }

第三種方法,約定每個線程只干自己的事

這種方法利用線程池本身就是隊列的方式,即先進先出。測試之后發(fā)現(xiàn)性能有下降,但是還是貼出來供參考。

      static int threadCount = 2;
        static int count = 0;
        static object cursorLock = new object();
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            Task[] arr = new Task[2];
            for (int threadIndex = 0; threadIndex < threadCount; threadIndex++)
            {
                //這兩種方法都可以
                arr[threadIndex] = Task.Factory.StartNew(PrintNum, threadIndex);
            }
            Task.WaitAll(arr);
            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds);
            Console.Read();
        }


        private static void PrintNum(object num)
        {
            bool isOk = false;
            while (!isOk)
            {
                lock (cursorLock)
                {
                    int index = count % 2;
                    if (count>100)
                    {
                        isOk = true;
                    }
                    else if (index == (int)num)
                    {
                        if (index == 0) Console.WriteLine("{0}:{1} {2} ", "偶數(shù)線程", Thread.CurrentThread.ManagedThreadId, count++);
                        else Console.WriteLine("{0}:{1} {2} ", "奇數(shù)線程", Thread.CurrentThread.ManagedThreadId, count++);
                    }
                }
            }
        }

結(jié)果如下:

第四種方法 Mutex

        private static int i = 0;
        static Mutex mutex = new Mutex();
     
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            //ThreadStart是個委托
            Thread thread1 = new Thread(new ParameterizedThreadStart(show));
            thread1.Name = "偶數(shù)線程";
            Thread thread2 = new Thread(new ParameterizedThreadStart(show));
            thread2.Name = "奇數(shù)線程";
            thread1.Start(0);
            thread2.Start(1);
            thread2.Join();
            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds);
            Console.Read();
        }
        /// <summary>
        /// Mutex的釋放與鎖定 都只能在同一個線程中執(zhí)行
        /// </summary>
        private static void show(object index)
        {
            while (i <= 100)
            {
                mutex.WaitOne();
                int num = i % 2;
                if (num == (int)index&&i<=100)
                {
                    Console.WriteLine("{0}:{1}  {2}  ", Thread.CurrentThread.Name, i++, Thread.CurrentThread.ManagedThreadId);
                }
                mutex.ReleaseMutex();
            }
           
        }

有關(guān)概念資料

http://m.fzitv.net/article/180789.htm

到此這篇關(guān)于C#中AutoResetEvent控制線程用法小結(jié)的文章就介紹到這了,更多相關(guān)AutoResetEvent控制線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#使用Spire.XLS for .NET將DataTable寫入Excel的具體步驟

    C#使用Spire.XLS for .NET將DataTable寫入Excel的具體步驟

    在日常開發(fā)中,我們經(jīng)常需要將 DataTable 中的數(shù)據(jù)導(dǎo)出到 Excel 文件中,方便用戶查看或進行后續(xù)分析,本文將介紹如何使用 Spire.XLS for .NET 實現(xiàn)這一功能,需要的朋友可以參考下
    2025-08-08
  • 解讀封送類、結(jié)構(gòu)體和聯(lián)合體實例

    解讀封送類、結(jié)構(gòu)體和聯(lián)合體實例

    本文主要介紹了.NETFramework中類、結(jié)構(gòu)體和聯(lián)合體的封送處理,包括類通過COM互操作封送為接口、結(jié)構(gòu)體通過StructLayoutAttribute屬性指定布局和封送方式,以及聯(lián)合體通過StructLayout(LayoutKind.Explicit)和FieldOffset特性精確控制內(nèi)存布局
    2025-01-01
  • C#組合函數(shù)的使用詳解

    C#組合函數(shù)的使用詳解

    本篇文章是對C#中的組合函數(shù)的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • C#難點逐個擊破(5):類的訪問類型

    C#難點逐個擊破(5):類的訪問類型

    類的訪問類型有時也叫訪問級別,使用以下訪問修改符:Public、Protected、Private、internal、protected internal。
    2010-02-02
  • C# 多線程處理List數(shù)據(jù)的示例代碼

    C# 多線程處理List數(shù)據(jù)的示例代碼

    這篇文章主要介紹了C# 多線程處理List數(shù)據(jù)的示例代碼,幫助大家更好的理解和使用c#編程語言,感興趣的朋友可以了解下
    2020-12-12
  • C#實現(xiàn)多線程的同步方法實例分析

    C#實現(xiàn)多線程的同步方法實例分析

    這篇文章主要介紹了C#實現(xiàn)多線程的同步方法,實例分析了C#線程同步的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • c#調(diào)用jar包的方法步驟(非常詳細)

    c#調(diào)用jar包的方法步驟(非常詳細)

    這篇文章主要給大家介紹了關(guān)于c#調(diào)用jar包的方法步驟,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C#中控制反轉(zhuǎn)和依賴注入原理及實現(xiàn)

    C#中控制反轉(zhuǎn)和依賴注入原理及實現(xiàn)

    本文深入探討了IoC(控制反轉(zhuǎn))和DI(依賴注入)的概念,及在面向?qū)ο缶幊讨械膽?yīng)用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • C#中使用DevExpress中的ChartControl實現(xiàn)極坐標圖的案例詳解

    C#中使用DevExpress中的ChartControl實現(xiàn)極坐標圖的案例詳解

    這篇文章主要介紹了在C#中使用DevExpress中的ChartControl實現(xiàn)極坐標圖,本案例是使用的是DevExpress 18.1.3版本,之前在14版本上也試過,但是有一個弊端就是實現(xiàn)極坐標圖的時候,第一個點和最后一個點總是自動多一條閉合線,會形成一個閉合的多邊形,因此升級了一下版
    2022-02-02
  • 基于WPF實現(xiàn)路徑圖標控件

    基于WPF實現(xiàn)路徑圖標控件

    這篇文章主要介紹了如何利用WPF實現(xiàn)路徑圖標控件,文中的示例代碼講解詳細,對我們學(xué)習(xí)或工作有一定幫助,需要的小伙伴可以參考一下
    2023-07-07

最新評論

六枝特区| 哈巴河县| 门头沟区| 芦溪县| 合肥市| 聂拉木县| 隆回县| 鹤庆县| 宣武区| 静宁县| 赤壁市| 光泽县| 潍坊市| 广昌县| 阳高县| 丹棱县| 奈曼旗| 绥滨县| 青田县| 天峻县| 图木舒克市| 巴青县| 庆阳市| 永嘉县| 栾川县| 北宁市| 茌平县| 赤壁市| 曲靖市| 济源市| 南漳县| 兰西县| 布拖县| 嘉义县| 祁连县| 常宁市| 龙南县| 枣阳市| 衡山县| 同心县| 若尔盖县|