如何停止一个线程
面试官想考察什么?
- 是否对线程的用法有所了解(初级)
- 是否对线程的stop()方法有所了解(初级)
- 是否对线程的stop过程中存在的问题有所认识(中级)
- 是否熟悉interrupt中断的用法(中级)
- 是否能解释清除使用boolean标志位的好处(高级)
- 是否知道interrupt底层的细节(高级)
- 是否能通过该题目转移话题到线程安全,并阐述无误(高级)
剖析题目: 停止线程
停止线程有stop()方法,但是已经废弃(因为直接stop一个线程会有锁以及资源没有被释放的问题)
- 以上所述,不能简单的停止一个线程(而应该将线程中任务全部执行完毕或者关闭,让线程任务终止而结束)
- 如何设计可以随时被中断而取消的任务线程
线程是协作的任务执行模式
- 通知目标线程自动结束,而不是强制停止
- 目标线程应具备处理中断的能力
- 中断方式
- interrupt
- boolean标志位
interrupt(原生支持)
sleep(){
sleep方法会捕获InterruptEcaption,当我们调用thread.interrupt() 就可以在catch中处理任务,任务全部结束,线程就会关闭
}如果线程里有很多次循环是不支持interrupt的{
我们可以添加判断来支持interrupt
例:``java for(int i = 0 , i <10000,i++){ if(interrupted()){ true->中断 break; } todo... }
并且调用thread.interrupt() 这样for的时候就可以判断并且break.
``
}
interrupted() 于 isInterrupted()
- interrupted()是静态方法,获取当前线程的中断状态,并清空。
- 当前运行的线程
- 中断状态调用后清空,重复调用后续返回false
- isInterrupted()是非静态方法,获取该线程的中断状态,不清空
- 调用线程对象对应的线程
- 可重复调用,中断请空前一直返回true.
-区别{
在JNI源码中 interrupted()调用的是底层线程的对象self的interrupted()
isInterrupted()JNI会找到JavaThread底层对应的C++线程实例随后调用它的isInterrupted()方法
底层interrupted()于isInterrupted()方法不同的在于前者在多调用了清空当前中断状态的方法,并且方法里面加了wait_mutex锁,后者则没有。
}
volatile Boolean标志位
在线程中添加volatile boolean 对象标志位(其实就是对象)
在线程外更改这个boolean的值,在线程中不断地if这个标志位即可
为什么要使用volatile?{
volatile 保持该标志位的可见性,因为调用者于对象存在的不在一个线程中,在java的内存模型上,可能会导致不可见
而且相对于其他线程来说,该标志位是可见的,所以需要加volatile锁保持标志位的原子性与可见性(因为执行时不一定是正常顺序)
}
interrupted与Boolean对比
- 需要支持系统方法时用中断用interrupted()(功能性)
- 其他情况用Boolean标志位(性能)