zoukankan      html  css  js  c++  java
  • 线程实用解析(二)创建调用有参函数的线程和线程池简介

         上一节主要是对线程有一个具体的介绍,同时也介绍了线程调用无参函数的方法,这一节主要介绍线程调用有参甚至是多参函数,同时也会进一步的介绍线程池。

         先介绍线程调用有参函数

         一、调用有一个参数的函数

    static void Main(string[] args)

            {

                //标记显示主线程ID   

                Console.WriteLine("主线程的ID:" + Thread.CurrentThread.ManagedThreadId);

                //如果线程要调用有参函数,这时线程的构造函数的参数应为一个ParameterizedThreadStart的实例对象,函数参数必须为Object类型

                Thread thread = new Thread(new ParameterizedThreadStart(ParamMethod));                                  

                thread.Start("Olive");

               //同时还可以用lambda表达式进行传值,这个时候可以传任意类型的值和任意多个参数

                Thread thread1=new Thread(()=>ParamMethod("Olive");

                Thread1.Start();

                Console.ReadKey();

            }

            private static void ParamMethod(object name)

            {

                Console.WriteLine("当前的线程ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示当前线程ID

                Console.WriteLine("Hello WorldMy gril's name is:" + name); 

            }

    效果如图

    二、调用有多个参数的构造函数

    线程调用含有多个参数的函数主要有以下几种方法。

    1、将所需要的传递的数据封装成一个类

     例如:

           先建一个类,将要传递的信息包含其中

     public class Student

        {

            public string Name

            { get;  set; }

            public string Sex

            { get;  set; }

            public int Age

            { get;  set; }

            public string Address

            { get; set;}

    }

    具体的实现如下:

    static void Main(string[] args)

            {

           Student student = new Student()

                {

                    Name = "Olve",

                    Sex = "",

                    Age = 22,

                    Address = "北京"

                };

     

                Console.WriteLine("主线程的ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示主线程ID

                Thread thread = new Thread(new ParameterizedThreadStart(ParamMethod));

                thread.Start(student);

                Console.ReadKey();

            }

     

    private static void ParamMethod(object obj)

            {

                Console.WriteLine("当前的线程ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示当前线程ID

                Student student = (Student)obj;//因为传递的参数为Object类型的这里要强制转换下

                Console.WriteLine("Hello WorldMy gril's name is  " + student.Name);

                Console.WriteLine("and her age is "+student.Age);

                Console.WriteLine("Now,She is in "+student.Address);

            }

    2、使用lambda表达式传递多个参数

       通过使用lambda表达式传递多个参数和传递一个参数是一样的

    具体看代码

    Main函数里代码:

    Thread thread=new Thread(()=>TestShow("Olive","22","北京"));

    thread.Start();

     

    Private static void (object name,object age,object address)

    {

     Console("My girl's name is"+name+"Age is"+age+"Address is"+address);

     

    介绍完了线程调用有参函数的传参,下面再介绍下线程池。

    创建线程是需要时间的,每个线程也会被分配一些内存。许多应用程序一般都使用多个线程进行协同工作,为了简化对这些线程的管理,.NET框架为每一个进程提供了一个线程池,使应用程序能够根据需要来有效地利用多个线程。线程池线程都是后台线程。每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。

    在这里首先要感谢下上一节中给我指出错误的兄弟,实在是抱歉由于我的一时疏忽,将通过Thread类创建的线程写成是后台线程,这确实是大错特错的。先介绍下什么是前台线程、什么是后台线程。

    前台线程:线程默认为前台线程,只要有一个前台线程在运行,程序就一直运行、存活。

    后台线程:当所有的前台线程结束之后,程序就会结束,不论后台线程是否运行结束,程序都会将后台线程给Kill掉。 

    在默认情况下,用Thread 类创建的线程都是前台线程。线程池中的线程总是后台线程.

    在用Thread类创建线程时,可以设置属性IsBackground,以确定该线程是(false)前台线程还是(true)后台线程。一般使用时多将线程设置为后台线程,这样在程序关闭时可以立即释放资源,有时候我们会发现明明一个程序已经关闭了,但是查看任务管理器发现它还在占用一些内存,就是因为还有些前台线程没有执行完毕的缘故。

    线程池特别适合于执行一些需要多个线程的任务。使用线程池能够优化这些任务的执行过程,从而提高吞吐量,它不仅能够使系统针对此进程优化该执行过程,而且还能够使系统针对计算机上的其他进程优化该执行过程。但是同时它也有一些限制比如:不能把线程池中的线程改为前台线程不能给线程池中的线程设置优先级或名称线程池中的线程只能用于时间较短的任务,如果用时较长,应使用Thread类创建实例。

    下面介绍线程池的主要用法:

    System.Threading.ThreadPool类实现了线程池,该类是一个静态类。最长用的是

    ThreadPool.QueueUserWorkItem(WaitCallback waitcallback ,object state)

    该函数有两个参数一个是WaitCallBack类型的委托,一个是状态,可以作为传递单个的参数,如果需要传递多个参数,可以先将参数封装成类,传递类对象。

    ThreadPool.QueueUserWorkItem方法在线程池中创建一个线程池线程来执行指定的方法(用委托WaitCallback来表示),并将该线程排入线程池的队列等待执行

    具体使用如下:

    Main函数代码如下:

    {

                string s="Olive";

                ThreadPool.QueueUserWorkItem(new WaitCallback(Count), s);

    }

    Private static Count(object name)

    {

      Console.WriteLine("Hello ! My Name is  "+name);

    }

    每个进程都有且只有一个线程池。当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。

     

    这一节就介绍到这里了,下一节会介绍线程的同步相关的知识。希望能对朋友们有一点帮助,如果有说的不对的地方,还请各位多多指教!

  • 相关阅读:
    flask基础 MUI
    flask基础 MongoDB
    falsk 基础 语音识别与语音合成()
    flask基础 websocket ()
    flask基础四 请求上下文()
    flask基础三
    学习整理
    Elasticsearch
    课程学习:Linux系统管理
    课程学习:程序设计与算法
  • 原文地址:https://www.cnblogs.com/Olive116/p/2712007.html
Copyright © 2011-2022 走看看