首页 > 代码库 > 线程基本知识
线程基本知识
首先来说说概念,一个进程至少会有一个进程,当然一个进程中也可以开启多个线程。我们就可以让一个程序在同一时间看上去能做多个事情,比如可以在接受用户响应的时候进行一些计算。
线程也不可以随便开,普通应用程序来说每一个线程默认情况下都会占用1M的栈空间,在32位Windows平台下可以给一个用户进程使用的程序最大在2G,那么也就是 说在程序中使用的线程不能超过2000个,在实际测试中可以发现
一般来说开1930左右个线程就会收到内存不足的异常,其实这个数量是绝对够用的,即使复 杂的Outlook2007程序一般也只用了50个不到的线程。
在不得已的情况下很多人都不太会去使用多线程也是有原因的,一是因为多线程编程复杂,要尽量分割任务让它在多个线程中使用以利用到多个处理器核。还有就是多个线程使用相同资源的话还要考虑资源的锁定以免产生数据的不一
致。锁定/事务 /并发的概念在数据库中也是非常常见的。
二是因为调试困难,特别是一个线程的执行依赖其它线程的执行。
三是因为多线程的程序随着环境的变化(处理器/操作 系统)可能执行的性能还不一定相同,如果只针对某个环境进行编程可能还不能充分利用多处理器的优势。比如我们对一个任务划分成2个线程并行执行,那么对于 四核的处理器来
说,划分成4个线程并行执行会不会更合理呢
首先来看看如何创建线程:
Console.WriteLine(Process.GetCurrentProcess().Threads.Count); //进程里面的线程数//开启线程,线程传入参数Thread t1 = new Thread(() => { Thread.Sleep(1000);//延时,休眠1分钟再执行 Thread t = Thread.CurrentThread; Console.WriteLine("Name: " + t.Name); //托管线程的唯一标识符,微软建议使用托管线程的Id而不是操作系统中线程的Id来跟踪线程。 Console.WriteLine("ManagedThreadId: " + t.ManagedThreadId); Console.WriteLine("State: " + t.ThreadState); Console.WriteLine("Priority: " + t.Priority); //是否马上结束.teue:指示该线程为后台线程。后台线程将会随着主线程的退出而退出。当主线程退出的时候,IsBackground=FALSE的线程还会继续执行下去,直到线程执行结束 Console.WriteLine("IsBackground: " + t.IsBackground); //表明这个线程不是由线程池创建的 Console.WriteLine("IsThreadPoolThread: " + t.IsThreadPoolThread); }) { Name = "Thread1", //为线程设置名字 Priority = ThreadPriority.Highest//设置线程的有限级Highest最高优先 Lowest最低优先 };t1.Start(); //结束Console.WriteLine(Process.GetCurrentProcess().Threads.Count);
用线程调用方法:
new Thread(Add(1, 2)).Start();static void Add(int i, int j){ Console.WriteLine(i + j);}
控制台是在等待着用户输入,输入完则调用线程
线程中的阻塞用Join完成
Thread t3 = new Thread(() => { for (int k = 0; k < 10; k++) { Thread.Sleep(100); Console.Write("1"); } Console.WriteLine(); });Thread t4 = new Thread(() =>{ for (int k = 0; k < 10; k++) { Thread.Sleep(100); Console.Write("2"); } Console.WriteLine();});t3.Start();t3.Join(TimeSpan.FromMilliseconds(500));t4.Start();Console.WriteLine();
输出来的结果是:11111 121212121212 2222
启动t3之后,我们让主线程阻塞500毫秒,这样的话t3应该已经输出若干X了,在阻塞的同时,然后启动t4,t3和t4交替输出X和Y,最后500毫秒由于t3已经结束,所以只会输出2:
线程同步问题
在两个线程里面对静态变量做更改,然后访问同一个静态变量,每次都不一样。这个就是存在同步问题
线程同步就是指线程的步调一致,如果一个线程没有完成我们就等,一直等到它完成
可以用t1.IsAlive(顾名思义,它表示线程当前是否为可用状态,如果线程已经启动,并且当前没有任何异常的话,则返回true,否则为false)循环的去询问是否可用的,如果可用了则执行下一个进程
但是这样导致资源浪费。用Join()来阻塞主线程一直到次线程的计算任务完成。采用锁机制进行同步的方法
线程基本知识