1. 什么是停止线程
停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。
2. 错误的方式 - 调用Thread.stop()方法
虽然停止一个线程可以用Thread.stop()方法,但最好不要用它。它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。使用这个方法可能会导致数据出现破坏,甚至导致程序的流程出现错误。
3. 如何正确的停止线程
有以下2种方法可以终止正在运行的线程:
1). 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2). 使用interrupt方法中断线程。
4. 使用退出标志退出线程
我们可以使用volatile修饰的boolean标识位的方式来停止线程:
public classInterruptThread {public static void main(String[] args) throwsInterruptedException {
InterruptableThread interruptableThread= newInterruptableThread();
interruptableThread.start();
Thread.sleep(6);
interruptableThread.isStopped= true;
}static class InterruptableThread extendsThread {public volatile boolean isStopped = false;
@Overridepublic voidrun() {super.run();for (int i = 0; i < 10000000 ; i++) {if(isStopped) {
System.out.println("i = " +i);return;
}
}
}
}
}
输出内容:
i = 1647062
可以看到循环遍历并没有执行完,就停止了,说明此方式能够做到退出线程。这里使用volatile修饰是为了防止因为多线程访问同一字段出现可见性的问题。
5. 使用 Thread.interrupt() 方法停止线程
使用interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。
下面我们举两个例子,都是使用了interrupt()方法,但是一个不能够停止线程执行,另一个就能停止线程执行。
如下面的代码,即使我们调用了interrupt(),线程也不会停止执行:
public class MyThread extendsThread {public voidrun(){super.run();for(int i=0; i<500000; i++){
System.out.println("i="+(i+1));
}
}
}public classRun {public static voidmain(String args[]){
Thread thread= newMyThread();
thread.start();try{
Thread.sleep(2000);
thread.interrupt();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
其输出结果:
...
i=499994i=499995i=499996i=499997i=499998i=499999i=500000
使用interrupt()方法,能够终止线程的执行的正确方式如下:
public class MyThread extendsThread {public voidrun(){super.run();for(int i=0; i<500000; i++){if(this.interrupted()) {return;
}
System.out.println("i="+(i+1));
}
}
}public classRun {public static voidmain(String args[]){
Thread thread= newMyThread();
thread.start();try{
Thread.sleep(2000);
thread.interrupt();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:
...
i=202053i=202054i=202055i=202056
6. 判断线程是否停止的方法
Thread方法提供了两个方法来判断线程是否停止:interrupted()、isInterrupted()。
interrupted()是静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态。
isInterrupted()是实例方法,是调用该方法的对象所表示的那个线程的isInterrupted(),不会重置当前线程的中断状态。