C# 创建线程的多种方式之Thread类基础知识

摘要:
默认情况下,Thread类创建的线程是前台线程,也可以通过设置IsBackground属性将其更改为后台线程,而线程池创建的线程则是后台线程。如下图所示,控制台ReadLine();禁用该命令后,控制台窗口不会立即消失,而是等待t1线程结束。如果线程是CPU密集型的,则其优先级低于定义的基本优先级。中断()未提及上述内容。调用此函数后,将出现InterruptException,然后将唤醒处于WaitSleepJoin状态的线程。

1. Thread类创建线程

该类的构造函数可以接受ThreadStart委托参数(定义了无参,返回void的函数),以及ParameterizedThreadStart委托参数(定义了Object参数,返回void的函数)。

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread(Calculate);
            t1.Start(10);
            Console.WriteLine("Main is over");
            Console.ReadLine();
        }

        private static void Calculate(object obj)
        {
            int sum = 0;
            int total = (int)obj;
            for (int i = 0; i < total;i++ )
            {
                sum += i;
                Thread.Sleep(100);
            }
             Console.WriteLine("Sum is "+sum);
        }

当然Thread类也可以和Lamda表达式一起使用,实现与上面同样的功能:

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread((obj) =>
            {
                int sum = 0;
                int total = (int)obj;
                for (int i = 0; i < total; i++)
                {
                    sum += i;
                    Thread.Sleep(100);
                }
                Console.WriteLine("Sum is " + sum);
            });
            t1.Start(10);
            Console.WriteLine("Main is over");
            Console.ReadLine();
        }

2. 后台线程

只要有一个前台在运行,应用进程就不会停止运行,而后台线程的运行则不会影响应用进程的结束,前,后台线程在线程优先级及其他方面并无差异。在默认情况下,Thread类创建的线程都是前台线程,也可以通过设置IsBackground属性改变为后台线程,而线程池创建的均为后台线程。如下,将Console.ReadLine();指令禁用,运行发现控制台窗体不会马上消失,而是会等待t1线程运行结束。

        static void Main(string[] args)
        {
            
            Console.WriteLine("Main Start....");
            Thread t1 = new Thread((obj) =>
            {
                int sum = 0;
                int total = (int)obj;
                for (int i = 0; i < total; i++)
                {
                    sum += i;
                    Thread.Sleep(100);
                }
                Console.WriteLine("Sum is " + sum);
            });
            t1.Start(10);
            Console.WriteLine("Main is over");
            //Console.ReadLine();
        }

3. 线程优先级

线程优先级用Priority属性表示,定义的级别有Highest, AboveNormal, BelowNormal, Lowest, 操作系统会根据优先级去调度线程。如果有优先级相同的几个线程在运行,就用得上时间量和循环的规则。如果线程是CPU密集型的(一直需要CPU不等待的),其优先级就低于定义的基本优先级。

4.线程的控制及状态

 ThreadState 为线程定义了一组所有可能的执行状态。一旦线程被创建,它就至少处于其中一个状态中,直到终止。因为是各种状态的组合,所以在判断当前线程状态的时候就需要用位运算,而不能简单的使用等号(有个例外,Runing状态值为0,所以用与运算不行)。

 Unstarted : 创建线程,但为调用Run();

 Runing: 调用Run()后,当线程正在被CPU调用;

WaitSleepJoin:线程等待,调用Sleep(), Join()会进入该状态,其中Join()会阻塞当前线程,直到被调用线程运行结束或中止;

Stopped:线程运行结束后,进入该状态,该状态下无法通过Start(),重新启动线程,必须重新创建线程;

Background:当线程的IsBackground属性设置为true后,创建线程后调用线程前,状态为Unstarted+Background,而调用线程后状态为Runing+Background,sleep()后状态为WaitSleepJoin+Background,线程结束后状态为Stopped;

AbortRequested:当线程调用Abort(),处理完ThreadAbortException前,此时可以调用ResetAbort(),取消中止操作;

Aborted:当线程调用Abort(),处理完ThreadAbortException后;

SuspendRequested:当线程调用Suspend()后,线程被挂起前;

Suspended:线程已经被挂起,此时可用Resume(),继续运行;

控制线程的常用函数在上面基本上已经提到,其中Suspend(), Resume()已经不推荐使用,因为线程挂起可能会造成一些不可预知的问题,例如线程死锁,可以使用线程同步的一些类来代替使用。另外,Abort()也是不推荐使用的,可以定义布尔状态量来代替使用。Interrupt()上面未提到,调用这个函数后,会出现InterruptException,接着唤醒处于WaitSleepJoin状态的线程。

免责声明:文章转载自《C# 创建线程的多种方式之Thread类基础知识》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CSerialPort类的源码(程序文件和头文件)redis开机自动启动服务下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Jmeter-测试计划元件

打开Jmeter页面,默认显示测试计划和工作台: 1、测试计划: 用来描述一个性能测试,包含与本次性能测试所有相关的功能。也就说性能测试的所有内容是于基于一个计划的。 右键单击“测试计划”弹出菜单: 注意: 测试计划中“函数测试模式”复选框,如果被选择,它会使Jmeter记录来自服务器返回的每个取样的数据。如果你在测试监听器中选择一个文件,这个数据将被写...

android 在子线程中使用handler更新界面

1. 在子线程中创建一个handler对象,让这个handler对象获取主线程的looper,这样才能把这个handler中的消息发送到ui线程的消息队列中 下面这个界面当点击updateui按钮就会创建一个对象然后调用它的更新图片和文字的方法,这两个设置方法在子线程中执行。 在更新界面的对象的类中创建一个handler对象,在初始化的时候给他赋值为Lo...

Java并发编程-多线程

1、进程与线程   一个程序就是一个进程,一个程序中的多个任务被称为线程。进程是资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位。多线程的好处并发执行提高了程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态 2、线程的实现方式 继承java.lang.Thread类 实现java.lang.Runnable接口,然后交...

C#多线程(二)

一、线程池每次创建一个线程,都会花费几百微秒级别的时间来创建一个私有的局部栈,每个线程默认使用1M的内存。这个可以在使用Thread类的构造函数时设置: [csharp] view plaincopyprint?  new Thread(new ThreadStart(Go), 2);   new Thread(new ParameterizedT...

阿里云负载均衡升级:同城容灾进一步提升可用性

为了向广大SLB用户提供更加稳定可靠的负载均衡服务,近期阿里云对其SLB系统进行了升级,优先在杭州和青岛地域部署了同城容灾的本地高可用解决方案,下面就让我们一起来了解一下SLB同城容灾方案。 什么是同城容灾? SLB集群本身,已经实现了各种冗余,包括电力、网络、服务器等。我们单集群可以防止“单路电力故障”、“单边网络故障”、“服务硬件故障”、“系统意外宕机...

IOS多线程--回调主线程

回调主线程 (1)NSThread 1.performSelectorOnMainThread调用主线程的方法、 [self performSelectorOnMainThread:@selector(finish) withObject:self waitUntilDone:NO]; 2.回调其她子线程也是可以的,但是不用 self performSel...