C#多线程实践——提前释放锁
一个被阻止的线程可以通过两种方式被提前释放:
- 使用Thread.Interrupt
- 使用Thread.Abort
释放一个线程的锁必须通过另外活动的线程实现,等待的线程自己是不能对它的被阻止状态做任何事情。
Interrupt方法
在一个被阻止的线程上调用Interrupt 方法,将强制释放它,同时抛出ThreadInterruptedException异常,如下:
class Program { static void Main() { Thread t = new Thread (delegate() { try { Thread.Sleep (Timeout.Infinite); } catch (ThreadInterruptedException) { Console.Write ("Forcibly "); } Console.WriteLine ("Woken!"); }); t.Start(); t.Interrupt(); } } Output: Forcibly Woken!
中断一个线程仅仅释放它的当前的(或下一个)等待状态,并不结束这个线程(当然,除非未处理ThreadInterruptedException异常)。
如果Interrupt被一个未阻止的线程调用,那么线程将继续执行直到下一次被阻止时,它抛出ThreadInterruptedException异常。用下面的测试避免这个问题,不过这不是一个线程安全的方式。
if ((worker.ThreadState & ThreadState.WaitSleepJoin) > 0) worker.Interrupt();
随意中断线程有很大风险,因为任何框架或第三方方法在调用堆栈时都可能意外地在已订阅的代码上收到中断。如果这个方法没有被设计成可以被中断(没有适当处理finally块)的对象,可能剩下无用的状态,或资源释放不完全。如果确切知道应该在哪儿中断,中断一个线程也是安全的,比如信号系统。
Abort方法
被阻止的线程也可以通过Abort方法被强制释放,除了用ThreadAbortException异常代替了ThreadInterruptedException异常,与调用Interrupt相似。异常将被抛出在catch里,直到Thread.ResetAbort在catch中被调用,在这期间线程的ThreadState为AbortRequested。
Interrupt 与 Abort 之间最大不同在于它们调用一个非阻止线程所发生的事情。Interrupt继续工作直到下一次阻止发生,Abort在线程当前所执行的位置(可能甚至不在你的代码中)抛出异常。终止一个非阻止的线程会带来严重的后果。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。