Java应用线程泄漏原因分析与避免(3)

这种阻塞的线程,一般调用的函数都会强制检查并抛出interruption异常,类似的还有wait(),阻塞队列的take等,为了程序能正常关闭,InterruptedException最好不好忽略。

public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println("wake up");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("stop...");
                    break;
                }
            }
        }
    });
    t.start();
    t.interrupt();
}

如果run方法里没有抛出InterruptedException怎么办?例如下面这个

public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            int i = 0;
            while (true) {
                i++;
            }
        }
    });
    t.start();
    t.interrupt();
}

这种情况就需要run方法里不断检查是否被中断了,否则永远停不下来。

public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            int i = 0;
            while (true) {
                i++;
                if(Thread.interrupted()) {
                    System.out.println("stop..");
                    break;
                }
            }
        }
    });
    t.start();
    t.interrupt();
}

上面就是正确停止单个线程的方法,对于线程池,一般有两个方法,shutdown和shutdownNow,这两个方法差别是很大的,shutdown只是线程池不再接受新的任务,但是不会打断正在运行的线程,而shutdownNow会对逐个线程调用interrupt方法,如果你的线程是确定可以在一段时间跑完的,可以用shutdown,但是如果是一个死循环,或者在sleep需要很长时间才重新唤醒,那就用shutdownNow,然后对于Runnable的实现也需要遵循上面单个线程的原则。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/08bdfa1167151db31faf3977f12dda95.html