欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于C#線程的全面解析

 更新時間:2022年04月20日 09:01:20   作者:老虎中的小白Gentle  
這篇文章主要介紹了關(guān)于C#線程的全面解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

線程的作用和意義

線程 被定義為程序的執(zhí)行路徑。每個線程都定義了一個獨特的控制流。如果您的應(yīng)用程序涉及到復(fù)雜的和耗時的操作,那么設(shè)置不同的線程執(zhí)行路徑往往是有益的,每個線程執(zhí)行特定的工作。

線程是輕量級進程。一個使用線程的常見實例是現(xiàn)代操作系統(tǒng)中并行編程的實現(xiàn)。使用線程節(jié)省了 CPU 周期的浪費,同時提高了應(yīng)用程序的效率。

到目前為止我們編寫的程序是一個單線程作為應(yīng)用程序的運行實例的單一的過程運行的。但是,這樣子應(yīng)用程序同時只能執(zhí)行一個任務(wù)。為了同時執(zhí)行多個任務(wù),它可以被劃分為更小的線程。

線程生命周期

線程生命周期開始于 System.Threading.Thread 類的對象被創(chuàng)建時,結(jié)束于線程被終止或完成執(zhí)行時。

下面列出了線程生命周期中的各種狀態(tài):

  • 未啟動狀態(tài):當(dāng)線程實例被創(chuàng)建但 Start 方法未被調(diào)用時的狀況。
  • 就緒狀態(tài):當(dāng)線程準(zhǔn)備好運行并等待 CPU 周期時的狀況。
  • 不可運行狀態(tài):下面的幾種情況下線程是不可運行的:
    • 已經(jīng)調(diào)用 Sleep 方法
    • 已經(jīng)調(diào)用 Wait 方法
    • 通過 I/O 操作阻塞
  • 死亡狀態(tài):當(dāng)線程已完成執(zhí)行或已中止時的狀況

C#創(chuàng)建線程

在C# 語言中使用線程時首先需要創(chuàng)建線程,在使用 Thread 類的構(gòu)造方法創(chuàng)建其實例時,需要用到 ThreadStart 委托或者 ParameterizedThreadStart 委托創(chuàng)建 Thread 類的實例。ThreadStart 委托只能用于無返回值、無參數(shù)的方法,而ParameterizedThreadStart 委托則可以用于帶參數(shù)的方法。

ThreadStar的方式創(chuàng)建

例子:

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        //線程函數(shù)
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
        }
        static void Main(string[] args)
        {
            //創(chuàng)建ThreadStart的委托實例
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            //創(chuàng)建Thread類的實例
            Thread childThread = new Thread(childref);
            childThread.Start(); //開始一個線程
            Console.ReadKey();
        }
    }
}

運行結(jié)果:

ParameterizedThreadStart

例子:

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //創(chuàng)建一個線程委托對象
            ParameterizedThreadStart pts = new ParameterizedThreadStart(PrintEven);
            Console.WriteLine("In Main: Creating the Child thread");
           // 創(chuàng)建一個線程對象
            Thread childThread = new Thread(pts);
            childThread.Start(10);
            Console.ReadKey();
        }
        //線程跑的函數(shù)
        //打印0~n中的偶數(shù)
        private static void PrintEven(Object n)
        {
            Console.WriteLine("Child thread started");
            for(int i=0; i<=(int)n; i+=2) //類型轉(zhuǎn)換
            {
                Console.WriteLine(i);
            }
        }
    }
}

運行結(jié)果:

C#讓線程休眠一會

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
            int sleepfor = 5000;
            Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
            Thread.Sleep(sleepfor);  //讓線程暫停 單位毫秒
            Console.WriteLine("Child thread resumes");
        }
        static void Main(string[] args)
        {
            //創(chuàng)建一個線程的委托
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            //創(chuàng)建線程的實例
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

運行結(jié)果:最后一行是5s后才打印出來的

C#銷毀線程

/*
 銷毀線程
 */
using System;
using System.Threading;
namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        //委托函數(shù)
        public static void CallToChildThread()
        {
            try//引起異常的語句
            {
                Console.WriteLine("Child thread starts");
                for(int counter = 0; counter <= 10; counter++)
                {
                    Thread.Sleep(500);
                    Console.WriteLine(counter);
                }
                Console.WriteLine("Child Thread Completed");
                   
            }
            catch(ThreadAbortException e)//錯誤處理代碼
            {
                Console.WriteLine("Thread Abort Exception");
            }
            finally //執(zhí)行的語句
            {
                Console.WriteLine("Could't catch the Thread Exception");
            }
        }
        static void Main(string[] args)
        {
            //創(chuàng)建一個線程的委托實例
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            //創(chuàng)建一個線程對象
            Thread childThread = new Thread(childref);
            childThread.Start();
            //主線程休眠
            Thread.Sleep(2000);
            Console.WriteLine("In Main:Aborting the Child thread");
            //在調(diào)用此方法的線程上引發(fā)ThreadAbortException,以開始終止此線程的過程。
            //調(diào)用此方法通常會終止線程
            childThread.Abort();
            Console.ReadKey();
        }
    }
}

運行結(jié)果:

C#線程優(yōu)先級

在C#中線程的優(yōu)先級使用線程的Priority屬性設(shè)置即可,默認(rèn)的優(yōu)先級是Normal。在設(shè)置優(yōu)先級后,優(yōu)先級高的線程將優(yōu)先執(zhí)行。優(yōu)先級的值通關(guān)ThreadPriority枚舉類型來設(shè)置,從低到高分別為Lowest 、BelowNormal、Normal、 AboveNormal、 Highest。

例子:

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class Program
    {
        //奇數(shù)
        public static void PrintOdd()
        {
            Console.WriteLine("List of odd numbers:");
            for (int i = 1; i <= 100; i += 2)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }
        //偶數(shù)
        public static void PrintEven()
        {
            Console.WriteLine("List of even numbers: ");
            for(int i = 0; i<=100; i+=2)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            //創(chuàng)建線程的委托1
            ThreadStart childref1 = new ThreadStart(PrintEven);
            Console.WriteLine("In Main: Creating the Child1 thread");
            //創(chuàng)建線程1的實例
            Thread childThread1 = new Thread(childref1);
            //設(shè)置打印偶數(shù)優(yōu)先級為最低 
            childThread1.Priority = ThreadPriority.Lowest;
            //創(chuàng)建線程的委托2
            ThreadStart childref2 = new ThreadStart(PrintOdd);
            Console.WriteLine("In Main: Creating the Child2 thread");
            //創(chuàng)建線程2的實例
            Thread childThread2 = new Thread(childref2);
            //設(shè)置打印奇數(shù)優(yōu)先級為最高 
            childThread2.Priority = ThreadPriority.Highest;
            childThread1.Start();//偶數(shù)  低
            childThread2.Start();//奇數(shù)  高
            Console.ReadKey();
        }
    }
}

運行的結(jié)果:

第一次運行:

第二次:

第三次:

第四次:

小結(jié):

從上面的運行效果可以看出,由于輸岀奇數(shù)的線程的優(yōu)先級高于輸出偶數(shù)的線程,所以在輸出結(jié)果中優(yōu)先輸出奇數(shù)的次數(shù)會更多。

此外,每次輸出的結(jié)果也不是固定的。通過優(yōu)先級是不能控制線程中的先后執(zhí)行順序的,只能是優(yōu)先級高的線程優(yōu)先執(zhí)行的次數(shù)多而已。

線程狀態(tài)控制的方法包括暫停線程 (Sleep)、中斷線程 (Interrupt)、掛起線程 (Suspend)、喚醒線程 (Resume)、終止線程 (Abort)。

lock:給線程加鎖,保證線程同步

sleep 方法能控制線程的暫停時間,從而改變多個線程之間的先后順序,但每次調(diào)用線程的結(jié)果是隨機的。線程同步的方法是將線程資源共享,允許控制每次執(zhí)行一個線程,并交替執(zhí)行每個線程。在 C# 語言中實現(xiàn)線程同步可以使用 lock 關(guān)鍵字和 Monitor 類、Mutex 類來解決。對于線程同步操作最簡單的一種方式就是使用 lock 關(guān)鍵字,通過 lock 關(guān)鍵字能保證加鎖的線程只有在執(zhí)行完成后才能執(zhí)行其他線程。

lock的語法如下

lock(object)
 {
    //臨界區(qū)代碼
 }

這里 lock 后面通常是一個 Object 類型的值,也可以使用 this 關(guān)鍵字來表示。

最好是在 lock 中使用私有的非靜態(tài)或負(fù)變量或私有的靜態(tài)成員變量,即使用 Private 或 Private static 修飾的成員。

例如:

private Object obj = new Object();
lock (obj)
{
    //臨界區(qū)代碼
}

一個更具體的實例

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class Program
    {
        //打印偶數(shù)
        public void PrintEven()
        {
            //lock上鎖保證執(zhí)行完該線程才跑其他線程
           lock(this)
            {
                for(int i=0; i<=10; i+=2)
                {
                    //獲取當(dāng)前線程的名字
                    Console.WriteLine(Thread.CurrentThread.Name + "--" + i);
                }
            }
        }
        //打印奇數(shù)
        public void PrintOdd()
        {
            lock (this)
            {
                for (int i = 1; i <= 10; i += 2)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + "--" + i);
                }
            }
        }
        static void Main(string[] args)
        {
            //因為下面要用到program類中的非靜態(tài)函數(shù),所以先創(chuàng)建該類對象
            Program program = new Program();
            //創(chuàng)建線程1的托管
            ThreadStart ts1 = new ThreadStart(program.PrintOdd);
            //創(chuàng)建線程1
            Thread t1 = new Thread(ts1);
            t1.Name = "打印奇數(shù)的線程";
            //跑線程1
            t1.Start();
            ThreadStart ts2 = new ThreadStart(program.PrintEven);
            Thread t2 = new Thread(ts2);
            t2.Name = "打印偶數(shù)的線程";
            t2.Start();
        }
    }
        
  
   
}

運行結(jié)果:

Monitor:鎖定資源

和lock用法本質(zhì)是一樣的,使用Monitor類鎖定資源的語法如下:

Monitor.Enter(object);
try
{
    //臨界區(qū)代碼
}
finally
{
    Monitor.Exit(object);
}

這里的object與lock中的object一樣。

具體例子

sing System;
using System.Threading;
namespace MultithreadingApplication
{
    class Program
    {
        public void PrintEven()
        {
            //在指定對象上獲取排它鎖
            Monitor.Enter(this);
            try//臨界區(qū)代碼
            {
                for(int i=0; i<=10; i+=2)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + "--" + i);
                }
            }
            finally
            {
                //釋放指定對象的排它鎖
                Monitor.Exit(this);
            }
        }
        public void PrintOdd()
        {
            Monitor.Enter(this);
            try
            {
                for(int i=1; i<=10; i+=2)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + "--" + i);
                }
            }
            finally
            {
                Monitor.Exit(this);
            }
        }
        static void Main(string[] args)
        {
            //下面創(chuàng)建委托對象時調(diào)用的是Program類的非靜態(tài)方法,
            //所先創(chuàng)建一個program對象
            Program program = new Program();
            //實例化一個委托
            ThreadStart ts1 = new ThreadStart(program.PrintOdd);
            //創(chuàng)建一個線程
            Thread t1 = new Thread(ts1);
            //給線程名字賦值
            t1.Name = "打印奇數(shù)的線程";
            //開跑線程
            t1.Start();
            ThreadStart ts2 = new ThreadStart(program.PrintEven);
            Thread t2 = new Thread(ts2);
            t2.Name = "打印偶數(shù)的線程";
            t2.Start();
        }
    }
}

運行結(jié)果:

Monitor 類的用法雖然比 lock 關(guān)鍵字復(fù)雜,但其能添加等待獲得鎖定的超時值,這樣就不會無限期等待獲得對象鎖。使用 TryEnter() 方法可以給它傳送一個超時值,決定等待獲得對象鎖的最長時間。

使用 TryEnter() 方法設(shè)置獲得對象鎖的時間的語法如下:

Monitor.TryEnter(object, 毫秒數(shù) );

Mutex:互斥鎖

Mutex類也是用于線程同步操作的類,當(dāng)多個線程同時訪問一個資源識保證只有一個線程訪問資源。在Mutex類中,WaitOne()方法用于等待資源被釋放,ReleaseMutex()方法用于釋放資源。 WaitOne()方法在等待ReleMutex()方法執(zhí)行后才會結(jié)束。

例子:

using System;
using System.Threading;
namespace MultithreadingApplication
{
    class Program
    {
        //創(chuàng)建一個鎖對象
        private static Mutex mutex = new Mutex();
        public static void PakingSpace(object num)
        {
            if(mutex.WaitOne())//等待釋放資源,當(dāng)前資源沒調(diào)用時為true
            {
                try
                {
                    Console.WriteLine("車牌號{0}的車駛?cè)耄?, num);
                    Thread.Sleep(1000);//線程休眠一秒
                }
                finally
                {
                    Console.WriteLine("車牌號{0}的車離開!", num);
                    mutex.ReleaseMutex(); //釋放鎖資源
                }
            }
        }
        static void Main(string[] args)
        {
            //創(chuàng)建一個委托帶參數(shù)的
            ParameterizedThreadStart ts = new ParameterizedThreadStart(PakingSpace);
            //創(chuàng)建一個線程
            Thread t1 = new Thread(ts);
            t1.Start("A123456");
            Thread t2 = new Thread(ts);
            t2.Start("B00000");
            Console.ReadKey();
        }
    }
}

運行結(jié)果:

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#制作網(wǎng)站掛機程序的實現(xiàn)示例

    C#制作網(wǎng)站掛機程序的實現(xiàn)示例

    本文主要介紹了C#制作網(wǎng)站掛機程序,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 詳解c# 泛型類的功能

    詳解c# 泛型類的功能

    這篇文章主要介紹了c# 泛型類的功能,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2020-10-10
  • Url相對路徑的問題總結(jié)

    Url相對路徑的問題總結(jié)

    很多時候,我們在圖片或者其他(a標(biāo)簽,flash)中指定鏈接的時候,我們需要選擇是使用絕對路徑,或者是相對路徑.
    2012-11-11
  • C#中的多線程超時處理實踐方案

    C#中的多線程超時處理實踐方案

    這篇文章主要介紹了C#中的多線程超時處理實踐方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-01-01
  • c#詳解datetime使用示例

    c#詳解datetime使用示例

    本文主要介紹了c# datetime使用示例,大家參考使用吧
    2014-05-05
  • C# FileStream實現(xiàn)多線程斷點續(xù)傳

    C# FileStream實現(xiàn)多線程斷點續(xù)傳

    這篇文章主要為大家詳細(xì)介紹了C# FileStream實現(xiàn)多線程斷點續(xù)傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Unity3D實戰(zhàn)之答題系統(tǒng)的實現(xiàn)

    Unity3D實戰(zhàn)之答題系統(tǒng)的實現(xiàn)

    本文將用Unity3D制作一個答題系統(tǒng),可以從文本文檔中提取題目和分?jǐn)?shù),然后綁定到UI上,在答題的過程中,自動判斷分?jǐn)?shù),自動判斷正確率。感興趣的可以學(xué)習(xí)一下
    2022-03-03
  • C#檢測DataSet是否為空的方法

    C#檢測DataSet是否為空的方法

    這篇文章主要介紹了C#檢測DataSet是否為空的方法,涉及C#操作DataSet的技巧,非常簡單實用,需要的朋友可以參考下
    2015-04-04
  • C# 生成隨機數(shù)的代碼

    C# 生成隨機數(shù)的代碼

    這篇文章主要介紹了C# 生成隨機數(shù)的代碼的相關(guān)資料,非常的簡單實用,需要的朋友可以參考下
    2015-03-03
  • c#中利用Tu Share獲取股票交易信息

    c#中利用Tu Share獲取股票交易信息

    這篇文章主要介紹了c#中利用Tu Share獲取股票交易信息,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06

最新評論