1.线程中断

当我们调用线程的interrupt方法,它有两个作用:

  1. 如果此线程处于阻塞状态(比如调用了wait方法,io等待),则会立马退出阻塞,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的处理,然后让线程退出。
  2. 如果此线程正处于运行之中,则线程不受任何影响,继续运行,仅仅是线程的中断标记被设置为true。所以线程要在适当的位置通过调用isInterrupted方法来查看自己是否被中断,并做退出操作。

注:

  1. 如果线程的interrupt方法先被调用,然后线程调用阻塞方法进入阻塞状态,InterruptedException异常依旧会抛出。
  2. 如果线程捕获InterruptedException异常后,继续调用阻塞方法,将不再触发InterruptedException异常

2.线程池的关闭

线程池提供了两个关闭方法,shutdownNow和shuwdown方法。

  1. shutdownNow方法的解释是:线程池拒接收新提交的任务,同时立马关闭线程池,线程池里的任务不再执行。
  2. shutdown方法的解释是:线程池拒接收新提交的任务,同时等待线程池里的任务执行完毕后关闭线程池。

2.1 shutdownNow

  1. 原子性的修改线程池的状态为stop
  2. 将队列里还没有执行的任务放到列表里,返回给调用方
  3. 遍历线程池里的所有工作线程,然后调用线程的interrupt方法。

将线程池状态修改为STOP,然后调用线程池里的所有线程的interrupt方法。将还没有执行的任务 返回给 调用方

正常情况下,线程池里的线程,就是在这个while循环里不停地执行。其中代码task.run()就是在执行我们提交给线程池的任务,如当我们调用shutdownNow时,task.run()里面正处于IO阻塞,则会导致报错,如果task.run()里正在正常执行,则不受影响,继续执行完这个任务。

android线程池怎么销毁 线程池关闭方法_java

2.2 shutdown

跟shutdownNow类似,只不过它是将线程池的状态修改为SHUTDOWN状态,然后调用interruptIdleWorkers方法,来中断空闲的线程。

跟shutdownNow方法调用interruptWorkers方法不同的是,interruptIdleWorkers方法在遍历线程池里的线程时,有一个w.tryLock()加锁判断,只有加锁成功的线程才会被调用interrupt方法。(就是正在执行线程池里任务的线程不会被中断)

android线程池怎么销毁 线程池关闭方法_java_02

3.优雅的关闭线程池

有了上边对两个关闭线程池方法的了解,相信优雅安全关闭线程池将不再是问题。

我们知道,使用shutdownNow方法,可能会引起报错,使用shutdown方法可能会导致线程关闭不了。

所以当我们使用shutdownNow方法关闭线程池时,一定要对任务里进行异常捕获。

当我们使用shuwdown方法关闭线程池时,一定要确保任务里不会有永久阻塞等待的逻辑,否则线程池就关闭不了。

最后,一定要记得,shutdownNow和shuwdown调用完,线程池并不是立马就关闭了,要想等待线程池关闭,还需调用awaitTermination方法来阻塞等待。

参考(其实就是复制):如何优雅的关闭线程池