Windows系统是一个多线程的操作系统,进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。
多线程的优点:
1.多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
2. 提高了CPU的利用率,就可以直接提高程序的整体执行速度
多线程的缺点:
1.线程开的越多,内存占用越大
2.协调和管理代码的难度加大,需要CPU时间跟踪线程
3.线程之间对资源的共享可能会产生可不遇知的问题
多线程定义:
不带参数线程:
private void Main() { Thread t1 = new Thread(new ThreadStart(ThreadMethod)); t1.IsBackground = true;//默认后台线程 t1.Start(); } private void ThreadMethod() { //Thread method }
带参数线程:ParameterizedThreadStart委托的参数类型必须是Object.
private void Main() { Thread t1 = new Thread(new ParameterizedThreadStart(ThreadMethod)); t1.IsBackground = true; t1.Start("thread param"); } private void ThreadMethod(object param) { //Thread method Console.WriteLine(param.toString()); }
使用匿名委托或Lamba表达式为Thread构造方法赋值:
//通过匿名委托创建 Thread thread1 = new Thread(delegate() { Console.WriteLine("我是通过匿名委托创建的线程"); }); thread1.Start(); //通过Lambda表达式创建 Thread thread2 = new Thread(() => Console.WriteLine("我是通过Lambda表达式创建的委托")); thread2.Start();
IsBackground :只有所有的前台线程都结束,应用程序才能结束,默认情况下创建的线程都是前台线程.只要所有的前台线程结束,后台线程自动结束。通过Thread.IsBackground设置后台线程。必须在调用Start方法之前设置线程的类型,否则一旦线程运行,将无法改变其类型.
Join:阻塞调用线程,直到该线程终止.
Abort:抛出 ThreadAbortException 异常让线程终止,终止后的线程不可唤醒
挂起(Suspend)和唤醒(Resume):已淘汰,由于线程的执行顺序和程序的执行情况不可预知,所以使用挂起和唤醒容易发生死锁的情况,在实际应用中应该尽量少用.
Sleep:把正在运行的线程挂起一段时间
Priority线程优先级:AboveNormal BelowNormal Highest Lowest Normal,默认为Normal.
线程池(ThreadPool):由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销. (使用情景:1.单个任务处理的时间比较短 2.需要处理的任务的数量大)
//设置线程池线程最大数,减少创建占用资源内存 ThreadPool.SetMaxThreads (int workerThreads,int completionPortThreads); //不带参数线程 ThreadPool.QueueUserWorkItem(new WaitCallback(方法名)); //带参数线程 ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 参数);
线程同步:是指在某一时刻只有一个线程可以访问变量,使用lock关键字.
Lock(expression) { //statement_block } /* expression代表你希望跟踪的对象: 如果你想保护一个类的实例,一般地,你可以使用this; 如果你想保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了 lock(this)尽量不要使用,this指的是整个外层方法,当锁住后导致别的进程也无法访问该方法,应lock一个不影响其他操作的私有对象 */
异步回调:如果想异步方法完成后执行某一操作,可以使用异步回调.
Action<string> action = this.DoSomethingLong; // 定义一个回调 AsyncCallback callback = p => { Console.WriteLine($"异步完成后执行"); }; // 回调作为参数 action.BeginInvoke("btnAsyncAdvanced_Click", callback, null);