线程1
来源:互联网 发布:肖八肖四选择题 知乎 编辑:程序博客网 时间:2024/05/17 08:05
启动线程(Starting Threads)
创建一个线程的最简单的方法就是创建Thread类的一个新的实例。让Thread构造函数接受一个参数—— 一个委托实例。CLR专门为这种用途提供了ThreadStart委托类,它会指向你的一个方法。它允许你构造一个线程,然后告诉你:“当你启动的时候,就执行这个方法”。ThreadStart委托声明如下:
public delegate void ThreadStart();
正如你所看到的,你挂接到这个委托的方法必须不带参数,而且必须返回void。所以,你可能像一下代码这样去创建一个新的线程:
Thread myThread = new Thread(new ThreadStart(myFunc));
例如,你可能创建两个工作现场,一个从零开始计数:
public void Incrementer()
{
for (int i = 0; i < 1000; i++)
{
System.Console.WriteLine("Incrementer :{0}",i);
}
}
另一个从1000往下计数
public void Incrementer()
{
for (int i = 0; i < 1000; i++)
{
System.Console.WriteLine("Incrementer :{0}",i);
}
}
为了在线程中运行它们,创建两个新线程,每一个使用一个ThreadStart委托进行初始化。这些委托各自使用成员函数进行初始化:
Thread t1 = new Thread(new ThreadStart(Incrementer));
Thread t2 = new Thread(new ThreadStart(Decrementer));
实例化了这些线程并没有让它们开始运行。为了运行它们你必须调用这些线程对象的Start方法。
t1.Start();
t2.Start();
你需要对System.Threading加上using语句让编译器知道Thread类。注意输出,你可以看到处理器在t1和t2之间切换。
class Program { static void Main(string[] args) { Program p = new Program(); Console.WriteLine("Hello"); //在静态方法Main()的外面执行它 p.DoTest(); Console.Read(); } public void DoTest() { //为Incrementer创建一个线程,并传入一个ThreadStart委托 //地址是Incrementer方法 Thread t1 = new Thread(new ThreadStart(Incrementer)); //为Decrementer创建一个线程,并传入一个ThreadStart委托 //地址是Decrementer方法 Thread t2 = new Thread(new ThreadStart(Decrementer)); //启动这些线程 t1.Start(); t2.Start(); } //演示函数,从上计数到1000 public void Incrementer() { for (int i = 0; i < 1000; i++) { System.Console.WriteLine("Incrementer :{0}",i); } } //演示函数,从1000向下计数 public void Decrementer() { for (int i = 1000; i >= 0; i--) { System.Console.WriteLine("Decrementer: {0}", i); } } }
处理器允许一个线程执行一段时间直到向上计数到809为止。然后,第二个线程就会被执行,并且从60先下计数一段时间。然后,第一个线程又会 被允许执行。
拼接线程(连接线程)
当你暂停一个线程,让它等到另一个线程完成之后在继续,你是在把第一个线程拼接到第二个。相当于你把第一个的头部系到第二个的尾部,从而把它们拼接起来。
为了把线程1(t1)拼接到线程2(t2),写入代码:
t2.Join();
如果这个语句在线程t1的一个函数中运行,t1将会挂起等待,直到t2完成并且推出。例如你会需要Main()所在的线程等待所有其他的线程运行完毕,再打印它的结束信息。在下一个代码片断,假设你创建了一个线程集合名叫myThreads。遍历这个集合,一次把当前的线程拼接到集合中的线程:
foreah(Thread myThread in myThreads)
{
myThread.Join();
}
Console.WriteLine("All my threads are done.");
最后一个消息“All my threads are done.” 直到所有的线程都运行完毕才会打印。在一个产品环境,你可能会建立一系列的线程完成某些任务(例如,打印、更新显示,等等),并且在这些工作线程都完成以前不想继续主线程的执行。
使用Sleep方法阻塞线程(Blocking Threads With Sleep)
有时,你希望暂停你的线程一小会儿。例如,你可能希望你的时钟线程暂停大约1秒钟才去测试系统时间。这让你可以不用花费上亿个机器时钟周期,就可以大约1秒钟才去显示一次新的时间。
Thread类为这种用途提供了一个公共的静态方法Sleep()。这个方法由几种重载形式,其中一个版本接受一个 整数参数,另一个接受一个timeSpan对象。这两种类型的参数都表示的是你希望线程暂停的毫秒数目,只不过是通过一个int或一个timespan对象来表示。
销毁线程(Killing Thread)
通常,线程在执行完它们的任务之后会消亡。不过,你可以让线程销毁它自身。最简明的方法是设置一个KeepAlive的布尔标志,让线程定期去检查这个标志。当标志的状态变化(例如从true变到false)时,线程可以停止自己的执行。
另一种方法是调用Thread.Interrupt方法,这会通知线程销毁自己。最终,万不得已的时候,如果你不管怎样都必须关闭你的应用程序,就可以调用Thread.Abort。这会导致一个ThreadAbortException异常被抛出,而线程可以捕捉这一异常。
- Java线程模型、线程状态 - 线程(1)
- 线程1
- 线程1
- 线程(1)
- 线程1
- 线程1
- 线程(1)
- 线程1
- 线程1
- 线程1
- 线程(1)
- 线程1
- 线程(1)----线程停止
- Linux 线程(1):线程概述
- java 线程1 线程分类
- 【线程】Java线程(1)-线程基本理解and实现方式
- Linux线程(1): 线程的创建
- 线程(一)线程基础(1)
- 如何实现iframe高度的自适应
- 2011面试题目之猴子偷桃
- android中的资源
- Android Path 使用
- 人人都能做的性能优化 web前端优化
- 线程1
- setLayout: Attempting to set QLayout "" on MainWindow "MainWindow", which already has a layout
- 要生存,先做一株小草
- QT中文乱码问题解决办法
- Android2.3.5系统源码下载
- 在线制作图片
- XP下完全删除ORACLE10g的方法
- C#+asp.net+sql数据库完成图片的保存与读取
- 不知道出处,转自人人java主页君