多线程编程笔记(一)
操作线程
1、操作实例
using System;
using System.Threading;
namespace AppThreadDemo
{
class App
{
static public void threadMethod()
{
Console.WriteLine("/n执行ThreadMethod的线程的代码为:{0}",Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(1000); //休眠1秒
}
static public void ThreadCreate()
{
Console.WriteLine("/n执行ThreadCreate的线程的代码为:{0}",Thread.CurrentThread.GetHashCode().ToString());
ThreadStart entry = new ThreadStart(App.threadMethod);//用线程体实例化Thread代理类
Thread thread = new Thread(entry);
thread.Start();
thread.Join();//等待线程结束
}
static public void Main()
{
ThreadCreate();
}
}
}
注意:
A、多个线程可以执行同一个线程体:
Thread thread = new Thread(entry);
Thread thread1 = new Thread(entry);
thread.Start();
thread1.Start();
thread.Join();
thread2.Join();
B、一个线程体执行结束后,不能调用其Start再次启动,试图通过对已终止的线程调用 Start 来重新启动已中止的线程将引发 ThreadStateException。
C、一个启动了的线程不能再次启动。试图通过对已运行的线程调用 Start 来重新启动已中止的线程将引发 ThreadStateException。
(对于B和C,《.net核心技术--原理与架构》中描述为SecurityException异常,用编译器是ThreadStateException异常。应该是笔误吧!)
2、结束线程
A、Abort
调用此方法后,在当前的线程上引发 ThreadAbortException,该异常终止此线程的过程。调用此方法通常会终止线程。
如果对尚未启动的线程调用 Abort,则在线程调用 Start 后再调用Abort 将该线程将中止。例如:
ThreadStart entry = new ThreadStart(App.threadMethod);
Thread thread = new Thread(entry);
Console.WriteLine("终止线程");
thread.Abort();
Console.WriteLine("启动线程");
thread.Start();
thread.Join();
Console.WriteLine("结束线程");
输出为:
终止线程
启动线程
结束线程
可以看出,执行这段代码后,Thread刚启动就马上死亡。
如果对已挂起的线程调用 Abort,则线程被重新开始后再执行Abort将该线程将中止。
如果对被阻塞或正在休眠的线程调用 Abort,则该线程被中断然后中止。
下面这段代码没有进行异常处理,所以异常向外传递,直到最后由公共运行库捕获。
using System;
using System.Threading;
namespace AppThreadDemo
{
class App
{
static public void threadMethod()
{
Console.WriteLine("/n执行ThreadMethod的线程的代码为:{0}",Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(1000);
Console.WriteLine("threadMethod线程结束");
}
static public void ThreadCreate()
{
Console.WriteLine("/n执行ThreadCreate的线程的代码为:{0}",Thread.CurrentThread.GetHashCode().ToString());
ThreadStart entry = new ThreadStart(App.threadMethod);
Thread thread = new Thread(entry);
Console.WriteLine("终止线程");
Console.WriteLine("启动线程");
thread.Start();
Thread.Sleep(500);//主线程休眠0.5秒,等待子线程运行
thread.Abort();
thread.Join();
Console.WriteLine("主线程结束");
}
static public void Main()
{
ThreadCreate();
}
}
}
输出为:
执行ThreadCreate的线程的代码为:1
终止线程
启动线程
执行ThreadMethod的线程的代码为:2
主线程结束
在threadMethod中,启动子线程后,主线程休眠0.5等待子线程执行,子线程执行threadMethod的第1句代码后,休眠1秒等待主线程运行。此当主线程休眠并调用Abort方法结束子线程的时候,子线程仍处于休眠状态。着时候子线程被打断,并结束。所以threadMethod的最后没机会执行。
若将threadMethod进行异常处理,
static public void threadMethod()
{
try
{
Console.WriteLine("/n执行ThreadMethod的线程的代码为:{0}",Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(1000);
}
catch(Exception e)
{
Console.WriteLine("捕获到异常:{0}",e.ToString());
}
finally
{
Console.WriteLine("threadMethod执行了finally块");
}
Console.WriteLine("threadMethod线程结束"); //这句在调用Abort是不会执行到的;Interrupt会执行到的
}
线程体就会捕获到了一个ThreadAbortException异常,而且finally块也执行了。
如果在执行非托管代码时线程忽略 ThreadAbortException,则当线程开始执行托管代码时,系统将再次引发 ThreadAbortException。
B、Interrupt
该方法打断一个处于WaitSleepJoin状态的线城。
在当前的线程调用该方法后产生ThreadInterruptedException异常。与Abort结束线程不同,调用Abort结束线程的方法将使该线程执行完Finally语句就结束,而调用Interrupt方法则允许线程执行完整个线程体后结束。
如果线程体不采取异常处理措施,则线程在被打断的时候立刻结束。
如果线程不处于WaitSleepJoin状态,则线程下次处于WaitSleepJoin时被打断。
摘自《.net核心技术--原理与架构》