java 线程的安全启停,通过标志位
在java线程中 stop() 方法,不推荐使用,为过期API,那么怎么安全的停止、退出线程?
可以通过使用标志位的方式实现:
我们定义一下结果参数,来控制线程的启停、退出
private boolean start = false; //启动标识
private boolean stop = false; //暂停标识
private boolean quit = false; //退出线程标识
接下来实现 Runnable 方法顶一个 Task 类
import java.util.concurrent.TimeUnit;
public class TaskRun implements Runnable {
private Object o = new Object();
private boolean start = false; //启动标识
private boolean stop = false; //暂停标识
private boolean quit = false; //退出标识
@Override
public void run() {
//启动是时候 将状态设置启动状态
this.start = true;
//其他标识设置为 false 状态
this.stop = false;
this.quit = false;
while (start) {
try {
System.err.println("run ---------------------");
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//挡退出状态为true时,退出
if (quit) {
this.start = false;
break;
}
//挡停止状态为 true时 休眠线程
if (stop) {
System.err.println("stop run---------------------");
synchronized (this) {
//设置 start 状态,用于外部检测状态
try {
this.start = false;
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.err.println("recovery run---------------------");
//恢复运行后,恢复相关状态
this.start = true;
this.stop = false;
}
}
}
public Object getO() {
return o;
}
public void setO(Object o) {
this.o = o;
}
public void stop() {
this.stop = true;
}
public void quit() {
this.quit = true;
}
public boolean restart() {
synchronized (this) {
this.notify();
}
return start;
}
public boolean isStart() {
return start;
}
public boolean isStop() {
return stop && !start;
}
public boolean isQuit() {
return quit;
}
}
接下来我们 编写一个测试
TaskRun taskRun = null;
Thread thread = null;
@RequestMapping(value = { "run/start" })
@ResponseBody
public Object start() {
if (taskRun == null || !taskRun.isStart()) {
taskRun = new TaskRun();
System.out.println("Start...");
thread = new Thread(taskRun, "AAAAAAAAAAAAAAAAAAAAAAAA");
thread.start();
while (!taskRun.isStart() && !thread.isAlive()) {
System.out.print("...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "ok";
} else {
return "已经启动";
}
}
@RequestMapping(value = { "run/restart" })
@ResponseBody
public String restart() {
System.out.println("Start...");
if (!taskRun.isStart()) {
taskRun.restart();
if(!thread.isAlive()){
System.out.println("new start...");
thread = new Thread(taskRun);
thread.start();
}
while (!taskRun.isStart()) {
System.out.print("...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "ok";
} else {
return "已经启动";
}
}
@RequestMapping(value = { "run/stop" })
@ResponseBody
public String stop() {
taskRun.stop();
System.out.println("stop");
while (!taskRun.isStop()) {
System.out.print("...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "ok";
}
@RequestMapping(value = { "run/quit" })
@ResponseBody
public String quit() {
taskRun.quit();
System.out.println("stop");
while (taskRun.isQuit() && thread.isAlive()) {
System.out.print("...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
taskRun = null;
thread = null;
return "ok";
}