线程的停止总共有三种方法
1.使用标志位,使得线程正常退出。
覆写run方法使得其为一个死循环,通过更改标志位退出循环。
代码演示:
线程类:
class TestThreadStop implements Runnable{
private boolean flag = true; // 标记位
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
while(flag){
System.out.println("我还在执行!");
}
System.out.println("我被终止了!");
}
}
测试代码:
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
TestThreadStop tts = new TestThreadStop();
Thread thread = new Thread(tts);
thread.start();
}
执行结果:因为run方法是一个死循环因此永远不会执行结束。
修改代码设置标记为false
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
TestThreadStop tts = new TestThreadStop();
Thread thread = new Thread(tts,"A线程");
thread.start();
Thread.sleep(100); // 主线程休眠0.1s确保A线程能执行几次
tts.setFlag(false);// 更改标记位
}
运行结果:线程A,很快被终止了。
2.调用stop方法
stop()是一个被抛弃的方法,该方法过于暴力,强行将执行到一半的线程终止,并且会立即释放该线程所获得的锁。此时我们并不知道线程执行到哪里了。因此不建议使用。
代码演示:
线程类:
class TestThreadStop implements Runnable{
@Override
public void run() {
while(true){
System.out.println("我还在执行!");
}
}
}
测试代码:
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
TestThreadStop tts = new TestThreadStop();
Thread thread = new Thread(tts,"A线程");
thread.start();
Thread.sleep(100);
thread.stop();
}
运行结果:
3 interrupt()方法
和该方法有关的有一个方法叫isInterrupted(),该方法是用来判断一个线程的状态,返回一个布尔值,true则表示该线程中断,否则则该线程不中断。
其中 interrupt()方法 并没有终止一个线程的能力,它仅仅是给调用它的线程发一个信号,即使得isInterrupted()的返回结果为true。表示你该终止了,具体是终止还是继续执行由处理者而定(一般都终止掉)。其中,中断信号发出后有两种可能:
-
当前线程处于正在执行的状态,则会将中断标志位置为true(之前该标志位都是false),因此就可以根据标志位得突变来终止线程(其实也是标记位的变换)。
-
线程处于阻塞的状态,且阻塞是由sleep,wait,join引起的,则会抛出一个中断异常,且将中断标志位仍设置为false。线程退出。
在第一种情况下,若后续处理中线程被阻塞则走第二种情况的流程。
代码演示:
class ThreadA implements Runnable{
@Override
public void run(){
while(true){
try {
Thread.sleep(10);
boolean state = Thread.currentThread().isInterru();
// 判断有没有收到中断信号
if(state){ // 非阻塞情况下
System.out.println("非阻塞情况下终止线程:" + state);
break;
}
} catch (InterruptedException e) { // 阻塞情况下调用interrupte()会抛该异常
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted());
// 退出阻塞状态,且中断标志位被自动清除,设置为false,即恢复之前的状态
return;
}
}
}
}
测试代码:
public static void main(String[] args) throws InterruptedException {
ThreadA threadA = new ThreadA();
Thread thread = new Thread(threadA);
thread.start();
Thread.currentThread().sleep(10);
thread.interrupt(); // 发出中断信号
}
其中运行结果是由具体得运行时间和阻塞时间谁长而定的,因为cpu的执行速度很块,因此只让线程睡10ms,以使得阻塞时间和运行时间差不多长。
运行结果一:正常情况下退出:
运行结果二:阻塞情况下的线程终止:
此时的线程中断位被重置为false。