假设这样一个场景,启动一个线程1
去完成某个任务,在这个任务还没有完成的时候,因为某种原因需要停止线程取消这个任务。但是Thread
并没有提供一个cancel()
方法,那么如何停止这个线程呢?Java提供了一种线程协作机制:interrupt()
。但是调用了线程1
的interrupt()
方法并不能让线程1
立刻终止退出,只是在告诉线程1
现在希望你终止运行,线程1
可以根据自身的运行情况确定终止的操作。这也就是为什么interrupt()
是一种线程协作机制的原因,因为这需要被调用该方法的线程配合采取行动线程才会真正停止。
为什么会使用这样的机制呢?为什么不调用了某个方法就立刻停止该线程的运行呢?这是考虑到线程中会占有一些资源,比如socket、DB或者文件读写连接,这是如果突然终止线程会导致资源无法被释放。解决方案就是告诉线程,运行应该被终止啦,你可以自行采取一些措施,确保线程终止后释放占用的资源,确保数据的安全完整。
那么线程如何配合采取行动实现协作停止运行机制呢?上代码:
class Task : Runnable {
override fun run() {
//do some operation
for (i in 0..1000) {
//check if the interrupt is called
if (Thread.currentThread().isInterrupted) {
//release the resource and quit the task
return
}
}
}
}
可以看到在循环中检查线程是否被要求终止,如果是的话采取相应措施并退出。查询线程是否被要求终止有两个方法Thread.currentThread().isInterrupted
和Thread.interrupted()
,区别在于前者只会返回当前线程Interrupt的状态,而后者在返回当前线程Interrupt的状态后会重置Interrupt为false
。
那么如何告诉调用Thread.interrupt()
的线程1
,执行任务的线程已经结束了呢?通过抛出InterruptedException()
即可。考虑到Java中实现Runnable
的run()
方法不能抛出异常(Kotlin不受此限制),可以使用Callable
代替。这和在Java中调用Thread.sleep()
方法为什么一定要用try{}catch{}
包裹起来的原因相同。
网友评论