使用volatile域保存状态
private static class MyThread extends Thread {
private volatile boolean isStop = false;
@Override
public void run() {
try {
while (!isStop) {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
}
public void cancel() {
isStop = true;
}
}
- 每次退出检测需要耗费一定的时间
- 如果在while内线程被阻塞了,线程可能永远无法结束
线程中断
- 每个线程都有一个boolean类型的中断状态
- interrupt()方法能够中断目标线程,isInterrupted()方法能够返回目标线程的中断状态,interrupted()方法能够清除线程的中断状态,并且返回之前的状态值,清除状态唯一的方法。
- 当线程处于阻塞(join,sleep,wait,sleep)的状态下,中断响应:清除中断的标记,抛出InterruptedException
- 当线程处于非阻塞的状态下,中断响应:保持中断状态
- 使用interrupted()方法一定要小心,因为会导致中断状态清除,应对方法,手动抛出InterruptedException或者调用interrupt()方法进行恢复中断
- 通常中断是实现线程取消的最合理的方法
private static class MyThread extends Thread {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
}
public void cancel() {
interrupt();
}
}
使用Future进行线程取消
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> task = executor.submit(runnable);
try {
task.get(1000, TimeUnit.MICROSECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
task.cancel(true);
}