public class Task implements Runnable{ public void run() { while(!Thread.interrupted()) { try { System.out.println("task"); TimeUnit.SECONDS.sleep(2); }catch (InterruptedException e) { System.out.println("interrupted"); } } } } public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new Task()); TimeUnit.SECONDS.sleep(10); exec.shutdownNow(); }
问题是我期待看到以下输出:
task task task task task interrupted
但是在我得到这个之后,程序会继续打印,直到我关闭它.
所以,我的问题是我做错了什么?为什么程序继续打印?
解决方法
The Interrupt Status Flag
The interrupt mechanism is implemented using
an internal flag known as the interrupt status. Invoking
Thread.interrupt sets this flag. When a thread checks for an interrupt
by invoking the static method Thread.interrupted,interrupt status is
cleared. The non-static isInterrupted method,which is used by one
thread to query the interrupt status of another,does not change the
interrupt status flag.By convention,any method that exits by throwing an
InterruptedException clears interrupt status when it does so. However,
it’s always possible that interrupt status will immediately be set
again,by another thread invoking interrupt.
因此,当你在循环中捕获InterruptedException时,中断的状态已经被重置,因此,下一次调用Thread.interrupted()将返回false,这反过来使while循环继续运行.要停止循环,您有以下选项:
>使用break退出循环>使用return退出整个方法>将try-catch-block移动到while循环外部(由Nathan Hughes建议)>在当前线程上调用interrupt()以再次设置中断标志>使用单独的布尔值来控制循环,并在catch块中相应地设置该标志>使用ScheduledExecutorService并从Runnable的run方法中删除循环,使任务成为重复任务