偶然有一次看到这个方法并不推荐使用,去探究一波原因。
调用interrupt()方法,只是将目标线程的 interrupted status
置为 true
,并不会暂停当前线程。这依赖目标线程的后续处理,假如没有处理,将不会出现期待的效果。要想中断线程,需要目标线程用 Thread.interrupted()
方法检查 interrupted status
,当状态为 true
时,应主动执行清理,并且抛出 InterruptedException
异常。
注: Thread.interrupted()
方法会清理状态(重置为 false
),而 Thread.currentThread.isInterrupted()
并不会清理状态,因此使用的时候要格外注意。
public static long runThread1(long max) throws InterruptedException { // 标注throws
long result = 0L;
for (long i = 0L; i < max; i++) {
result += i;
if (Thread.interrupted()) { // 重点:周期性检查自己是否被interrupt
throw new InterruptedException("Interrupted during summing"); // 主动中止
}
}
return result;
}
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(() -> {
try {
long result = runThread1(100000000L);
LOGGER.log(result);
} catch (InterruptedException ex) {
// 线程顶层方法,实现Runnable,不处理,正常中止。
LOGGER.log("worker thread stopped"); // 可以记录日志。
}
}, "meaningful-name");
thread1.start();
Thread.sleep(1000);
thread1.interrupt(); // 用interrupt()方法请求中止
thread1.join();
}
附带:Thread.yield()
方法的作用是暗示调度器收回目标线程的cpu资源,不一定会执行。如果执行了,效果就是目标线程放弃cpu资源,回归就绪态,重新与其他就绪状态的线程抢夺cpu资源。言外之意就是,我得到很多了,也给其他人一个“公平竞争”的机会。