廖雪峰Java11多线程编程-1线程的概念-5中断线程
1.中断线程:
- 如果线程需要执行一个长时间任务,就可能需要中断线程。场景:从网络上下载一个100M的文件,用户在下载过程中中断下载任务的执行。
- 中断线程就是其他线程给该线程发一个信号,该线程收到信号后结束执行run()方法
1.1中断线程
需要检测isInterrupted()标志,其他线程通过调用interrupt()方法中断该线程
class HelloThread extends Thread{
public void run(){
while(!isInterrupted()){
System.out.println("Hello");
}
}
}
class Main{
public static void main(String[] args) throws Exception{
Thread t = new HelloThread();
t.start();
Thread.sleep(1000);
t.interrupt();
}
}
1.2中断等待状态的线程
如果线程处于等待状态,该线程会捕获InterruptedException。捕获到InterruptedException说明有其他线程对其调用了interrupt()方法,通常情况下该线程应该立即结束运行。
class HelloThread extends Thread{
public void run(){
while(!isInterrupted()){
System.out.println("Hello");
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
return;
}
}
}
}
1.3设置running标志位中断线程
如果其他线程把HelloThread的标志位置设为false,while循环检测到running的值为false后,就会退出循环,结束run方法。
注意:线程间共享变量需要使用volatile关键字标记,确保线程能读取到更新后的变量值
class HelloThread extends Thread{
public volatile boolean running = true;
public void run(){
while(running){
System.out.println("Hello");
}
}
}
class Main{
public static void main(String[] args) throws Exception{
HelloThread t = new HelloThread();
t.start();
Thread.sleep(1000);
t.running = false;
}
}
![](https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190609194811228-1867666938.png)
![](https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190609195518456-1696848947.png)
volatile关键字的目的是告诉虚拟机:
- 每次访问变量时,总是获取主内存的最新值
- 每次修改变量后,立刻回写到到主内存
volatile关键字解决的是可见性问题:
- 当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值
2示例
2.1使用interrupt()中断线程
class InterrptThread extends Thread{
public void run(){
while(!isInterrupted()){
System.out.println("Hello");
try{
Thread.sleep(100);
}catch (InterruptedException ex){
System.out.println("Interrupted!");
break;
}
}
System.out.println("Thread end");
}
}
public class InterruptTest {
public static void main(String[] args) throws InterruptedException{
Thread t = new InterrptThread();
t.start();
Thread.sleep(1000);
t.interrupt();
System.out.println("main end");
}
}
![](https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190609191558629-1952532561.png)
![](https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190609192552171-1338826255.png)
3总结:
- 调用interrupt()方法可以中断一个线程
- 通过检测isInterrupted()标志获取当前线程是否已中断
- 如果线程处于等待状态,该线程会捕获InterruptedException
- isInterrupted()为true或者捕获了InterruptedException都应该立刻结束
- 通过标志位判断需要正确使用volatile关键字
- volatile关键字解决了共享变量在线程间的可见性问题