久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

多線程之旅(Thread)

 小世界的野孩子 2021-04-09

      在上篇文章中我們已經(jīng)知道了多線程是什么了,,那么它到底可以干嘛呢,?這里特別聲明一個前面的委托沒看的同學可以到上上上篇博文查看,,因為多線程要經(jīng)常使用到委托,。源碼

一,、異步,、同步

      1.同步(在計算的理解總是要你措不及防,,同步當線程做完一件事情之后,才會執(zhí)行后續(xù)動作),,同步方法慢,,只有一個線程執(zhí)行,異步方法快,,因為多個線程一起干活,,但是兩者并不是線性增長,當我們的異步線程占有的資源越來越多了,,會導致資源可能不夠,,其次線程過多CPU也是需要管理成本的,所以不是越多越好,。

      2.異步(可以同時執(zhí)行多個任務,,在同樣的時間,執(zhí)行不同的任務),,同步方法卡界面(UI),因為我們的主線程(UI)忙于計算造成了堵塞了,。異步方法不卡界面,計算任務交給了子線程完成,。winform中體現(xiàn)的玲玲精致,。(你品,你細品),,web 可以異步的處理一起其他的任務,比如給用戶發(fā)郵箱(我們的BS結(jié)構(gòu)的,,每次訪問都是一個子線程,,當我們的代碼寫的比較糟糕,是不是加載比較慢呢哈哈),。異步多線程無序,,執(zhí)行的先后無序,執(zhí)行的時間不確定,,結(jié)束也不確定,,所以我們很難通過執(zhí)行時間和先后順序控制,異步的執(zhí)行順序,。

二,、初識Thread

屬性名稱說明
CurrentContext獲取線程正在其中執(zhí)行的當前上下文。
CurrentThread獲取當前正在運行的線程,。
ExecutionContext獲取一個 ExecutionContext 對象,,該對象包含有關當前線程的各種上下文的信息。
IsAlive獲取一個值,,該值指示當前線程的執(zhí)行狀態(tài),。
IsBackground獲取或設置一個值,該值指示某個線程是否為后臺線程,。
IsThreadPoolThread獲取一個值,,該值指示線程是否屬于托管線程池。
ManagedThreadId獲取當前托管線程的唯一標識符,。
Name獲取或設置線程的名稱,。
Priority獲取或設置一個值,該值指示線程的調(diào)度優(yōu)先級,。
ThreadState獲取一個值,,該值包含當前線程的狀態(tài)。

Thread 中包括了多個方法來控制線程的創(chuàng)建,、掛起、停止,、銷毀,,后面的例子中會經(jīng)常使用。

方法名稱說明
Abort()    終止本線程,。
GetDomain()返回當前線程正在其中運行的當前域,。
GetDomainId()返回當前線程正在其中運行的當前域Id。
Interrupt()中斷處于 WaitSleepJoin 線程狀態(tài)的線程,。
Join()已重載,。 阻塞調(diào)用線程,直到某個線程終止時為止,。
Resume()繼續(xù)運行已掛起的線程,。
Start()  執(zhí)行本線程,。
Suspend()掛起當前線程,如果當前線程已屬于掛起狀態(tài)則此不起作用
Sleep()  把正在運行的線程掛起一段時間,。

      1.Thread是我們.NET 1.0 給我們提供的多線程類,,可以創(chuàng)建,和控制多線程,,Thread類構(gòu)造函數(shù)為接受ThreadStart和ParameterizedThreadStart類型的委托參數(shù),,下面有請代碼神君。

        /// <summary>/// 使用Thread 創(chuàng)建多線程/// </summary>public static void Show()
        {//實例化創(chuàng)建線程 無參無返回值Thread thread = new Thread(() =>{
                Console.WriteLine("我是多線程");
            });
            thread.Start();//創(chuàng)建5個線程1for (int i = 0; i < 5; i++)
            {//這個之所以創(chuàng)建一個k,,后面線程不安全會說到var k = i;//這是一個有參數(shù)無返回值多線程new Thread(x => Running(Convert.ToInt32(x))).Start(k);
            }
            Console.Read();
        } /// <summary>/// 一個執(zhí)行需要長時間的任務/// </summary>static void Running(int s)
        {
            Console.WriteLine("**********************************");
            Console.WriteLine("執(zhí)行開始啦" + s);
            Console.WriteLine("獲取當前執(zhí)行的線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());var j = 0;for (int i = 0; i < 1000000000; i++)
            {
                j++;
            }
            Console.WriteLine("執(zhí)行結(jié)束啦" + s);
        }
View Code

二,、漸入佳境

  1.運行上面的代碼,可以看到線程的無序性,,雖然我們的0最先開始執(zhí)行的,,但是不是第一個結(jié)束的,這個是因為我們每個線程執(zhí)行的時間的不確定性,。這里也要特別說明為什么Thread構(gòu)造函數(shù)傳遞的是ThreadStart和ParameterizedThreadStart類型的委托參數(shù),,為什么不是Action ,F(xiàn)unc,,答案就是.NET 1.0的時候還沒有Action ,、Func。ThreadStart委托是一個無參無返回值上代碼中我們創(chuàng)建了,,ParameterizedThreadStart委托是一個有參數(shù)無返回值,,但是我們可以看到我們的參數(shù)是一個object類型,是一個不安全的參數(shù)(當時泛型也沒有出來)當然為了防止這問題,,我們也是想到了方法,,那就是我們可以通過一個泛型類,幫我們限制參數(shù)類型,。

        /// <summary>/// 防止參數(shù)不安全/// </summary>public static void Show5()
        {//我們創(chuàng)建一個泛型類,,限制我們的類型MyThread<string> mythread = new MyThread<string>("Thread_child");//將我們的方法傳遞,進去Thread th3 = new Thread(mythread.ThreadChild);//啟動線程            th3.Start();
        }/// <summary>/// 創(chuàng)建一個泛型類/// </summary>/// <typeparam name="T"></typeparam>class MyThread<T>{private T data;public MyThread(T data)
            {this.data = data;
            }public void ThreadChild()
            {
                Console.WriteLine("Child Thread Start! Result:{0}", data);
            }
        }
View Code

  2.我們在上面還提供了其他的方法,但是這些方法已經(jīng)不建議使用了,,現(xiàn)在已經(jīng)棄用了,,因為我們無法精確地控制線程的開啟與暫停,當我們將線程掛起的時候,,同時也會掛起線程使用的資源,,會導致死鎖,不建議使用,。將線程銷毀也不建議    不一定及時/有些動作發(fā)出收不回來,。(這里我使用的是.net Core 3.1 執(zhí)行直接報錯了哈哈)

        /// <summary>/// 使用Thread 線程掛起、喚醒線程、銷毀,,方式是拋異常,、取消Abort異常/// </summary>public static void Show1()
        {//創(chuàng)建一個Thread 線程Thread thread = new Thread(() =>{
                Running();
            });//開啟線程            thread.Start();//這個是線程掛起//thread.Suspend();//喚醒線程//thread.Resume();//上面的兩個方法,現(xiàn)在已經(jīng)棄用了,,因為我們無法精確地控制線程的開啟與暫停//當我們將線程掛起的時候,,同時也會掛起線程使用的資源,會導致死鎖,,不建議使用try{//將線程銷毀//也不建議    不一定及時/有些動作發(fā)出收不回來                thread.Abort();
            }catch (Exception)
            {//靜態(tài)方法將線程異常取消繼續(xù)工作                Thread.ResetAbort();
            }
            Console.Read();
        }
View Code

   3.線程優(yōu)先級,,當然我們的線程是一個無序的,也有控制線程執(zhí)行的權重,但是這個優(yōu)先級不是絕對的,,因為線程的執(zhí)行順序還是看我們的CPU爸爸的,,但是我們可以利用Priority屬性做線程的權重執(zhí)行,使用也很簡單

  /// <summary>/// 使用Thread 線程的優(yōu)先級(但是執(zhí)行還是看CPU,,可以做優(yōu)先級,,但是不是絕對優(yōu)先)/// </summary>public static void Show3()
        {//創(chuàng)建一個Thread 線程Thread thread = new Thread(() =>{
                Running();
            });
            thread.Start();//thread.Priority屬性可以設置線程的優(yōu)先級關系thread.Priority = ThreadPriority.Highest;
            Console.WriteLine("執(zhí)行完啦啦啦啦啦啦啦啦啦啦啦拉拉");
            Console.Read();
        }
View Code

  4.前臺線程、后臺線程(這個字面意思,,還是和我們的理解是不一樣的)我們設置IsBackground控制線程是否(前/后)臺線程,。默認是前臺線程,啟動之后一定要完成任務的,,阻止進程退出,。指定后臺線程:隨著進程退出。

 三,、多線程起飛

  1,、異步回調(diào)

    1.我們的Thread沒有給我提供異步回調(diào)的功能,沒辦法需要自己造輪子了,,我們可以先想一下回調(diào)的需求是什么,,需求分析:當我們的線程任務執(zhí)行完之后需要之后某些方法。我們細品一下,,我們要執(zhí)行完之后,,在執(zhí)行一個人任務,那就是同步執(zhí)行異步方法了吧,。我們在子線程中怎么同步執(zhí)行呢,?下面的代碼就實現(xiàn)了回調(diào)功能不管我們執(zhí)行多少次回調(diào)總會在任務后面執(zhí)行。

/// <summary>/// 異步回調(diào)執(zhí)行/// </summary>public static void Show6() {//創(chuàng)建一個任務委托ThreadStart threadStart = () => {
                Console.WriteLine("我是任務");
            };//創(chuàng)建一個回調(diào)執(zhí)行的委托Action action = () => {
                Console.WriteLine("哈哈,,我就是你們的回調(diào)方法哈,,記得雙擊么么噠");
                Console.WriteLine("*********************************************");
            };
            ThreadWithCallback(threadStart, action);
            Console.ReadLine();
        }/// <summary>/// 回調(diào)封裝 無返回值/// </summary>/// <param name="start"></param>/// <param name="callback">回調(diào)</param>private static void ThreadWithCallback(ThreadStart start, Action callback)
        {
            Thread thread = new Thread(() =>{
                start.Invoke();
                callback.Invoke();
            });
            thread.Start();
        }
View Code

   2,、返回參數(shù)

    1.當然我們使用線程需要返回參數(shù),,但是我們的Thread沒有給我們提供返回值的委托和方法,這個要莫子搞羅?當然我們先分析需求,,我們要獲取返回值是不是要等線程執(zhí)行之后呢,?好的線程執(zhí)行我們可以使用Join堵塞線程等它執(zhí)行完畢,但是我們要怎么獲取返回值呢,?對了我們可以創(chuàng)建一個變量,,我們的線程給變量賦值嗎?

/// <summary>/// 異步返回值/// </summary>public static void Show7()
        {//創(chuàng)建一個委托Func<string> func = () => {return "我是返回值";
            };//獲取執(zhí)行結(jié)果            Console.WriteLine(ThreadWithReturn(func).Invoke());
            Console.ReadLine();
        }/// <summary>/// 有返回值封裝(請根據(jù)本案例自行封裝回調(diào))/// </summary>/// <typeparam name="T">返回值類型</typeparam>/// <param name="func">需要子線程執(zhí)行的方法</param>/// <returns></returns>private static Func<T> ThreadWithReturn<T>(Func<T> func)
        {//初始化一個泛型,,限制我們的類型T t = default(T);
            ThreadStart newStart = () =>{//線程給變量賦值t = func.Invoke();
            };//創(chuàng)建線程Thread thread = new Thread(newStart);//執(zhí)行線程            thread.Start();//創(chuàng)建一個委托 無參有返回值,,執(zhí)行委托會發(fā)生執(zhí)行線程等待堵塞//當線程執(zhí)行完之后,也就是說線程已經(jīng)給變量t賦值了,,我們就返回treturn new Func<T>(() =>{
                thread.Join();return t;
            });
        }
View Code

 

 四,、Thread總結(jié)

  1.大家是不是覺得多線程很酷呢?哈哈我剛剛學的時候也是激動的心顫抖的手,。當然文章中我們介紹了很多API的使用,,大家可以動手試試,API的使用是小事,,最重要的是我們的思路,,到我們看到回調(diào)封裝和返回值封裝,我們都是利用了多線程的一些特性,,來完成的這些功能拓展的,。我們宏觀的看多線程感覺很恐怖,但是在我們做回調(diào)函數(shù)的時候是不是感覺有一種微觀看法,,線程執(zhí)行的內(nèi)部也是同步的執(zhí)行哪些方法的,。好了今天就寫到這里昨天晚上9點多就睡了,早起擼個文章美滋滋,。當然多線程還有講完的,,才說道了.NET 1.0哈哈,后續(xù)的文章也會寫出來,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多