今天有个同事问我Thread的Interrupe方法,这个方法用于终止另一个正在等待(Sleep/Wait/Join)状态的线程,如果那个线程未处于等待状态,则等到下次进入等待状态时再抛出。
这个方法的平时用的机会其实并不大,由于需要线程处于等待状态,很大程度上限制了使用的机会,因此问了下同事实际的使用场景,原来是某些线程进入了长时间的Sleep状态,而在某些情况下,可能某个任务发现可以取消其他一系列的任务时,需要尽快退出这些任务。这个时候使用Interrupe方法固然可以实现,不过显然也不太优雅,而且也更容易在未期待的地方抛异常,使程序进入不可控制的状态。
那么更优雅,更可控制的方法是什么哪?
结合这个业务场景,不难发现下面几个要求:
- 需要等待一定的时间(sleep)
- 需要在某个情况下快速退出等待
- 需要一组任务共享这个快速退出的信号
综合这些,不难发现通过那些信号量的等待和超时是再好不过了,不过,不同类型的信号量,其特性也有所不同。选择正确的信号量类型也很重要。
例如在这个场景下,如果使用AutoResetEvent的话,就很难做到一组任务共享这个快速退出的信号,而使用ManualResetEvent则很容易完成。
如何实现,或者说代码怎么写,这里就写个大概的思路:
任务组类型
私有ManualResetEvent,默认处于false状态下
公开Sleep方法,实现是调用ManualResetEvent的Wait方法,并返回bool,表示是因为时间到了而退出,还是因为收到了快速退出的信号
公开Stop方法,将ManualResetEvent的状态置为true
所有任务类型
当需要Sleep一定时间的,统一使用任务组提供的Sleep方法,并合理的处理返回值