C# Thread类 - 多线程学习1

最近要使用Hololens2 与PC 通信,然而Hololens2 在执行通信的任务的同时还有更重要的任务要做,因此就需要开启多线程,下面是我在此过程中摘录的一些关于多线程的知识点。

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

在没有使用线程之前,我们的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。

线程生命周期
线程生命周期开始于 System.Threading.Thread 类的对象被创建时,结束于线程被终止或完成执行时。
下面列出了线程生命周期中的各种状态

  • 未启动状态:当线程实例被创建但 Start 方法未被调用时的状况。
  • 就绪状态:当线程准备好运行并等待 CPU 周期时的状况。
  • 不可运行状态:下面的几种情况下线程是不可运行的:
    • 已经调用 Sleep 方法
    • 已经调用 Wait 方法
    • 通过 I/O 操作阻塞
  • 死亡状态:当线程已完成执行或已中止时的状况。

主线程
在 C# 中,System.Threading.Thread 类用于线程的工作。它允许创建并访问多线程应用程序中的单个线程。进程中第一个被执行的线程称为主线程。(C# 中的Task类也可以创建子线程,见下一篇文章解读)

当 C# 程序开始执行时,主线程自动创建。使用 Thread 类创建的线程被主线程的子线程调用。您可以使用 Thread 类的 CurrentThread 属性访问线程。

线程是通过扩展 Thread 类创建的。扩展的 Thread 类调用 Start() 方法来开始子线程的执行。
下面通过实例进行说明,下面实例共有六个线程,一个主线程,五个通过不同方式创建的子线程,大家可以自己看下输出中前三个线程输出的关系(结合线程执行内容中的sleep() 的时间进行分析)

代码有一丢丢长,耐心看完,直接从主函数入手。

using System;
using System.Threading;

namespace ch_Thread
{
    
    
    class Program
    {
    
    

        public static void CallChildThread1()
        {
    
    
            Thread thisTHread = Thread.CurrentThread;
            Console.WriteLine(thisTHread.Name + "-----------start----------");

            for (int counter = 1; counter <= 10; counter++)// 计数到 10
            {
    
    
                Thread.Sleep(200); // 线程休眠500ms
                Console.WriteLine(thisTHread.Name + counter.ToString());
            }

            Console.WriteLine(thisTHread.Name + "------------Completed--------------");
        }

        public static void CallChildThread2(object obj)
        {
    
    
            Thread thisTHread = Thread.CurrentThread;
            Console.WriteLine(thisTHread.Name + "-----------start----------");
            string str = obj as string;

            for (int counter = 1; counter <= 10; counter++)// 计数到 10
            {
    
    
                Thread.Sleep(400); // 线程休眠500ms
                Console.WriteLine(thisTHread.Name + str);
            }

            Console.WriteLine(thisTHread.Name + "------------Completed--------------");
        }

        public static void CallChildThread3() // 方法名字,自定义
        {
    
    

            Thread thisTHread = Thread.CurrentThread;
            Console.WriteLine(thisTHread.Name + "-----------start----------");

            for (int counter = 1; counter <= 10; counter++)// 计数到 10
            {
    
    
                Thread.Sleep(800); // 线程休眠1000ms
                Console.WriteLine(thisTHread.Name + counter.ToString());
            }

            Console.WriteLine(thisTHread.Name + "------------Completed--------------");
        }
        

        public static void DelegateThread4()
        {
    
    
            CallChild("==");
        }

        public static void CallChild(string b)
        {
    
    
            Thread theThread = Thread.CurrentThread;
            Console.WriteLine(theThread.Name + "-----------start----------");
            Console.WriteLine(theThread.Name + b);
            Console.WriteLine(theThread.Name + "------------Completed--------------");
        }


        static void Main(string[] args)
        {
    
    
            Thread thisTHread = Thread.CurrentThread; // 获取当前线程, 首先执行的,因此作为主线程
            Console.WriteLine("MainThread - ---------------------------------------");

            // 构建线程方法1
            Thread thread1 = new Thread(CallChildThread1);
            thread1.Name = "childThread - 1 - ";
            thread1.Start();

            // 构建线程方法2
            string myParam = "***************";
            ParameterizedThreadStart parameterized = new ParameterizedThreadStart(CallChildThread2);
            Thread thread2 = new Thread(parameterized);
            thread2.Name = "childThread - 2 - ";
            thread2.Start(myParam);

            // 构建线程方法3
            ThreadStart childThread3 = new ThreadStart(CallChildThread3); //ThreadStart是一个委托delegate, 指向一个没有参数,且没有返回值的方法。 这里对应CallToChildThread()方法,它即是无参数无返回值的方法。
            Thread thread3 = new Thread(childThread3);//Thread构造函数,实际上是创建了一个指向Test()方法的TreadStart委托对象
            thread3.Name = "childThread - 3 - - ";
            thread3.Start();

            Thread.Sleep(8100);  // 停止主线程一段时间

            // 构建线程方法4
            ThreadStart childThread4 = DelegateThread4;
            Thread thread4 = new Thread(childThread4);
            thread4.Name = "childThread - 4 - ";
            thread4.Start();

            // 构建线程方法5
            Thread thread5 = new Thread(() =>
            {
    
    
                CallChild("::");
            });
            thread5.Name = "childThread - 5 - ";
            thread5.Start();


            Console.WriteLine("MainThread -------------------------------------------");
            Console.ReadKey();
        }
    }
}

输出结果:

MainThread - ---------------------------------------
childThread - 3 - - -----------start----------
childThread - 2 - -----------start----------
childThread - 1 - -----------start----------
childThread - 1 - 1
childThread - 2 - ***************
childThread - 1 - 2
childThread - 1 - 3
childThread - 3 - - 1
childThread - 2 - ***************
childThread - 1 - 4
childThread - 1 - 5
childThread - 2 - ***************
childThread - 1 - 6
childThread - 1 - 7
childThread - 3 - - 2
childThread - 2 - ***************
childThread - 1 - 8
childThread - 1 - 9
childThread - 2 - ***************
childThread - 1 - 10
childThread - 1 - ------------Completed--------------
childThread - 3 - - 3
childThread - 2 - ***************
childThread - 2 - ***************
childThread - 3 - - 4
childThread - 2 - ***************
childThread - 2 - ***************
childThread - 3 - - 5
childThread - 2 - ***************
childThread - 2 - ------------Completed--------------
childThread - 3 - - 6
childThread - 3 - - 7
childThread - 3 - - 8
childThread - 3 - - 9
childThread - 3 - - 10
childThread - 3 - - ------------Completed--------------
childThread - 4 - -----------start----------
childThread - 4 - ==
childThread - 4 - ------------Completed--------------
MainThread -------------------------------------------
childThread - 5 - -----------start----------
childThread - 5 - ::
childThread - 5 - ------------Completed--------------

从输出结果上来看,五个线程互不影响,各自进行各自的。大家自己看前三个子线程输出内容的先后关系与各个线程中所写的休眠时间进行对比,会发现,,,你懂的哈哈哈。

这五种子线程采用了不同的创建方法,可以参考这篇文章内容介绍的关于多线程的知识点。

方法1为直接使用 Thread thread1 = new Thread(CallChildThread1) 创建
方法2为通过构造函数来创建线程对象,而且是带参数的构造函数,ParameterizedThreadStart是带参数委托
方法3和方法2类似,通过构造函数来创建线程对象,但是是不带参数的,ThreadStart是一个无参数委托
方法4和方法5其实和方法3是一样的,大家可以对比一下,只是形式有所不同。

猜你喜欢

转载自blog.csdn.net/ZhangJingHuaJYO/article/details/124358935