线程结束不推荐stop()方法,并且该方法已明确过时。因此有以下结束线程的方案
方法一:设一个volatile boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出
private static class Worker extends Thread{
private volatile boolean start=true;
@Override
public void run() {
while(start){
System.out.println("runing");
}
}
public void shutdown(){
this.start=false;
System.out.println("stop");
}
}
public static void main(String[] args) {
Worker worker=new Worker();
worker.start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.shutdown();
}
运行结果:
runing
runing
runing
runing
stop
方式二:捕获异常+中断状态标志判断
private static class Worker extends Thread{
public void run() {
while (!isInterrupted()){ //非阻塞过程中通过判断中断标志来退出
try{
Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
}catch(InterruptedException e){
e.printStackTrace();
break;//捕获到异常之后,执行break跳出循环。
//如果使用return,直接会将线程结束,如果while外面还有代码将不会执行
}
}
}
}
方式三:守护线程强制中断退出
因为有可能程序在中间阻塞,无法执行首位置的判断语句,因此需要一个强制退出的方案
public class ThreadService {
private Thread execuateThread;
private boolean isFinished;
private Long currentTimeMillis;
public void excute(Thread thread){//对要操作的Thread进行封装
execuateThread = new Thread(){
@Override
public void run() {
isFinished = false;
thread.setDaemon(true);//将要操作的线程thread设置为守护线程
thread.start();//开启要操作的thread线程
try {
thread.join();//阻塞当前线程execuateThread ,当检测到当前线程execuateThread打上中断标志后会抛出异常
} catch (InterruptedException e) {
System.out.println("线程超时被打断");
}
isFinished = true;
System.out.println("线程执行完成");//主线程执行完成,守护线程thread会自动结束。
}
};
execuateThread.start();
}
//等待mill毫秒后若线程还在运行则将其中断
public void stop(long mill){
currentTimeMillis = System.currentTimeMillis();
while (!isFinished){
if(System.currentTimeMillis()-currentTimeMillis>mill){
execuateThread.interrupt();
break;
}
}
}
}