多线程(三)
上一篇讲了多线程的创建,那么今天主要讲讲线程的终止。
线程的终止:
说完了线程的开始咱们接下来说说线程的结束
推荐使用的方法是调用interrupt( )方法来进行中断操作。大致的意思就是在线程A中调用线程B的interrupt( )方法,看作是A跟B说"你要中断啦!",然后B会在合适的时间进行中断,但他也完全可以不中断继续工作。因为java中的线程是协作式的,不是抢占式的,线程通过检查自身的中断标志位来判断是否中断。
这里面涉及到几个方法:
interrupt( ):发起中断请求,中断标志位设置为true
isInterrupted( ):这个是判断是否被中断,中断标志位是否为true
Thread.interrupted( )来进行判断当前线程是否被中断,不过Thread.interrupted( )会同时将中断标志位改为false。
如果一个线程在阻塞状态(调用了wait、join、sleep等),检查到中断标志位为true,则会在抛出interruptedException异常(看下图源码),并且会在抛出异常后将中断标志位设为false。那我们能不能自己创建个变量当作线程的结束标志呢?答案是可以的,但是存在缺陷(不推荐使用),当线程堵塞的时候,是无法检查自定义的结束标志,只有当阻塞结束了才能检测到这个结束标志位。所以用中断标志位比自己定义一个结束标志要好些,像wait、sleep等都支持中断的检查,并且自定义结束标志需要声明和占用资源。(注意这里的中断标志位和自定义的结束标志是不同的)
那么关于使用interrupt方法,我们编写一段代码来学习下。
class SelfThread extends Thread{
public void run(){
System.out.println(this.getName() + "线程运行了!!!!");
for (;;)
//判断线程中断标志位状态
if (!this.isInterrupted()) {
try {
//每次循环内都睡眠200毫秒并打印
Thread.sleep(200);
System.out.println(this.getName() + "running===============");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SelfThread st = new SelfThread();
st.start();
System.out.println(Thread.currentThread().getName()+"-------------");
try {
Thread.sleep(800);
//1.我们先不进行中断操作 2.然后将注解去掉进行中断操作
//st.interrupt();
//3.打开下面的注解,测试抛出了interruptException后中断标志位是否重置为false
//Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1.下面是不进行中断操作控制台打印的结果:不会抛出异常,正常结束
2.下面是进行中断操作的控制台打印结果:抛出了InterruptedException,原因就是线程属于堵塞状态下被中断。
3.下面是抛出中断异常后控制台打印的结果:可以看出中断标志位在抛出interruptedException异常后恢复为false
以上就是本节内容,谢谢大家的阅读,如有错漏,欢迎评论区指正提出😚!