zoukankan      html  css  js  c++  java
  • Thread类

      Thread类相对于线程池中的线程,使用者有更多的控制权。该类允许创建前台线程,设置线程优先级等。Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。

    1、给线程传递数据

      给线程传递数据的两种方式:

      1.使用带ParameterizedThreadStart委托参数的Thread构造函数:

    //定义一个数据类型,传递给线程
    public struct Data
    {
        public string Message;
    }
    //创建一个方法,将方法给线程的ParameterizedThreadStart委托
    static void ThreadMainWithParameters(object obj)
    {
        Data d = (Data)obj;
        Console.WriteLine("Running in a thread, received {0}", d.Message);
    }
    static void Main()
    {
        Data d = new Data { Message = "Info" };//创建一个数据实例
        Thread t2 = new Thread(ThreadMainWithParameters);//创建线程
        t2.Start(d);//启动线程,并传递参数
    }

      2.自定义一个类,把线程的方法定义为实例方法,然后初始化实例的数据后启动线程。

    //定义一个类,用于存放线程需要的数据和线程启动的方法
    public class MyThread
    {
        private string data;//线程数据
    
        public MyThread(string data)
        {
            this.data = data;
        }
        //线程启动方法
        public void ThreadMain()
        {
            Console.WriteLine("Running in a thread, data: {0}", data);
        }
    }
    static void Main()
    {
        MyThread obj = new MyThread("info");//创建实例信息
        Thread t3 = new Thread(obj.ThreadMain);//启动实例方法
        t3.Start();
    }

    2、后台线程

      如果应用程序内有任何一个前台线程在运行,那么应用程序就在运行。Thread类创建的线程默认时前台线程,线程池中创建的线程是后台线程。在使用Thread类创建线程时,可以设置IsBackground属性,以设置创建的Thread线程时后台线程还是前台线程。例如:

    //创建线程方法,以在主线程中调用
    static void ThreadMain()
    {
        Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name);
        Thread.Sleep(3000);
        Console.WriteLine("Thread {0} completed", Thread.CurrentThread.Name);
    }
    static void Main()
    {
        Thread t1 = new Thread(ThreadMain);
    t1.Name = "MyNewThread"; t1.Start();
       Thread.Sleep(100); Console.WriteLine(
    "Main thread ending now..."); /*******************输出********************
         *          Thread MyNewThread started * Main thread ending now... * Thread MyNewThread completed * ****************************************
    */ }

      可以看到,主线程先完成任务。但是主线程内启动的新线程是前台线程(默认),导致主线程结束任务后,新线程仍在写入控制台输出。如果在线程启动前,将线程的IsBackground属性设置为true,主线程结束时,会终止新线程的执行(不论是否完成任务)。

    static void Main()
    {
        Thread t1 = new Thread(ThreadMain);
        t1.Name = "MyNewThread";
        t1.IsBackground = true;
        t1.Start();
        Thread.Sleep(100);
        Console.WriteLine("Main thread ending now...");
        /*******************输出********************
         *          Thread MyNewThread started
         *          Main thread ending now...
         * *****************************************/
    }

      后台线程适合用于完成后台任务。

    3、线程的优先级

      线程由操作系统调度。给线程指定优先级,将影响线程调度顺序。优先级越高的线程,将会得到系统优先调度在CPU上运行。如果线程在等待资源,它就会停止运行,并释放CPU。

      线程必须等待的可能原因:响应睡眠指令、等待磁盘I/O完成、等待网络包到达等。如果线程不主动释放CPU,线程调度器就会抢占该线程。线程由一个时间量,它可以持续使用CPU,直到时间到达(如果没有更高优先级的线程时)。如果优先级相同的多个线程等待CPU,线程调度器会使用一个循环调度原则,将CPU逐一交个线程使用。如果线程被其他线程抢占,那么它会排队到最后去。

      只有优先级相同的多个线程同时在运行时,才能用上时间量循环规则。优先级是动态的:如果线程是CPU密集型,一直需要CPU,而且不等待资源,其优先级就降低为用该线程定义的基本优先级;如果线程在等待资源,它的优先级会提高。由于优先级的提高,所以线程可能在下一等待结束时获得CPU。

      线程的Priority属性,可以设置线程的优先级。线程指定优先级时,可能降低其他线程的运行概率。所以,可以根据需要短暂改变优先级。

    4、控制线程

      调用Thread对象的Start()方法可以创建线程。但是,新线程并不是出于Running状态,而是Unstarted状态。当线程调度器调用线程时,线程则会改为Running状态。其ThreadState属性可以获得线程的状态。

      线程类的静态方法Sleep(),会使线程处于WaitSleepJoin状态,在等待一段时间后,线程将再次被唤醒。

      如果要停止一个线程,可以调用方法Abort()。调用该方法,会在接到终止命令的线程中抛出ThreadAbortException类型异常。捕获该异常,可以在线程结束前做一些清理工作。如果再调用方法ResetAbort(),可能有机会再收到异常后继续运行。如果线程没有重置,接收到终止请求的线程的状态就从AbortRequested改为Aborted。

      调用Join()方法可以等待线程的结束。该方法会停止当前线程,并把它设置为WaitSleepJoin状态,直到加入的线程完成。

  • 相关阅读:
    Git 基础
    SharePoint 2013 对象模型操作"网站设置"菜单
    SharePoint 2013 隐藏部分Ribbon菜单
    SharePoint 2013 Designer系列之数据视图筛选
    SharePoint 2013 Designer系列之数据视图
    SharePoint 2013 Designer系列之自定义列表表单
    SharePoint 2013 设置自定义布局页
    SharePoint 2013 "通知我"功能简介
    SharePoint 2013 创建web应用程序报错"This page can’t be displayed"
    SharePoint 禁用本地回环的两个方法
  • 原文地址:https://www.cnblogs.com/pilgrim/p/9248810.html
Copyright © 2011-2022 走看看