乐趣区

关于java:记录-java-Intertupt-取消任务失效

每个线程对象里都有一个 boolean 类型的标识 (能够叫做中断标识),代表着是否有中断请求,能够应用这个标记位实现线程的终止性能。在最近的一个工作勾销的性能时,写下来如下代码:

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {while (!Thread.interrupted()) {
                    try {System.out.println("I am ok");
                        Thread.sleep(500);
                    } catch (Exception e) {logger.warn(...);
                    }
                }
            }
        });
        t.start();
     

而后在程序中适当的机会调用了 t.interupt()。满怀期待工作的进行。but 意外产生了,工作打印出了 ”java.lang.InterruptedException: sleep interrupted” 日志后,工作任然持续运行。
很显然中断标识被革除了。

查看 sleep 办法的阐明中有以下内容:

InterruptedException – if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

sleep 产生 InterruptedException 后,中断标识被革除。顺便咱们看看 InterruptedException 的阐明:

Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception. The following code can be used to achieve this effect:

if (Thread.interrupted())
   throw new InterruptedException();

当线程期待、休眠或以其余形式被占用,并且线程在流动之前或期间被中断时抛出。有时某个办法可能心愿测试以后线程是否已被中断,如果是,则立刻抛出此异样。上面的代码能够用来实现这个成果

if (Thread.interrupted())
   throw new InterruptedException();

批改原来的代码,捕捉 InterruptedExceion 并进行解决:

 Thread t = new Thread(new Runnable() {
            @Override
            public void run() {while (!Thread.interrupted()) {
                    try {System.out.println("I am ok");
                        Thread.sleep(500);
                    } catch (InterruptedException e) {Thread.currentThread().interrupt();} catch (Exception e) {e.printStackTrace();
                    }
                }
            }
        });
        t.start();

运行后能够 interupt 后 能够实现勾销性能。

总结: 当有 InterruptException 产生时,要进行解决,抛出异样或者再次标记中断标识。
特地是办法是给他人调用的最好不要吞掉中断,即捕捉到 InterruptedException 后在 catch 里什么也不做。

退出移动版