1. 使用标志位
public class ThreadEx implements Runnable {
private volatile boolean isStoped = false;
public void run() {
while (isStoped) {
// do something
}
}
public void stop {
isStoped = true;
}
}
上面这种方法当启动线程后在关闭时需要手动调用stop方法关闭线程,如果程序中只有一个线程后台运行,那么可以采用以下方式保证程序重新启动时,正确关闭上一次打开的后台线程,避免内存溢出。
public class Handler {
private static ThreadEx t;
public static void start() {
if (t != null)
t.stop();
t = new ThreadEx();
new Thread(t).satrt();
}
}
2. 使用中断
public class InterruptedExample {
public static void main(String[] args) throws Exception {
InterruptedExample interruptedExample = new InterruptedExample();
interruptedExample.start();
}
public void start() {
MyThread myThread = new MyThread();
myThread.start();
try {
Thread.sleep(3000);
myThread.cancel();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ThreadEx extends Thread{
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("interrupt");
// 注意异常处理
Thread.currentThread().interrupt();
}
}
System.out.println("stop");
}
public void stop(){
interrupt();
}
}
}
对线程调用interrupt()方法,不会真正中断正在运行的线程,只是发出一个请求,由线程在合适时候结束自己。正常情况下,线程接收到interrupt会在下一次判断中跳出循环,但是如果线程处于挂起状态,此时收到interrupt请求就会抛出异常,抛出InterruptedException后,中断标记会被重新设置为false,所以在InterruptedExample例子里,在接收到中断请求时,标准做法是执行Thread.currentThread().interrupt()恢复中断,让线程退出。
参考
http://www.jianshu.com/p/536b0df1fd55
http://blog.csdn.net/xplee0576/article/details/45133791