关于线程池

首先第一点,线程池是需要关闭的!!!

  1. try {  
  2.         // 向学生传达“问题解答完毕后请举手示意!”  
  3.         pool.shutdown();  
  4.    
  5.         // 向学生传达“XX分之内解答不完的问题全部带回去作为课后作业!”后老师等待学生答题  
  6.         // (所有的任务都结束的时候,返回TRUE)  
  7.         if(!pool.awaitTermination(awaitTime, TimeUnit.MILLISECONDS)){  
  8.             // 超时的时候向线程池中所有的线程发出中断(interrupted)。  
  9.             pool.shutdownNow();  
  10.         }  
  11.     } catch (InterruptedException e) {  
  12.         // awaitTermination方法被中断的时候也中止线程池中全部的线程的执行。  
  13.         System.out.println("awaitTermination interrupted: " + e);  
  14.         pool.shutdownNow();  
  15.     }  

shutdown也是很重要的

看了上面的描述后可能有些人会认为,只需要执行awaitTermination和shutdownNow就可以正常结束线程池中的线程了。其实不然。
shutdown方法还有「大家只解答我要求的问题,其它的不用多做」的意思在里面。

shutdown方法调用后,就不能再继续使用ExecutorService来追加新的任务了,如果继续调用execute方法执行新的任务的话

就会抛出RejectedExecutionException异常。(submit方法也会抛出上述异常)

而且,awaitTermination方法也不是在它被调用的时间点上简单得等待任务结束而是在awaitTermination方法调用后,

持续监视各个任务的状态以或者是否线程已经运行结束。所以不调用shutdown方法执行调用awaitTermination的话由于追加出来的任务可能

会导致任务状态监视出现偏差而发生预料之外的awaitTermination的Timeout异常

正确的调用顺序是

shutdown方法
awaitTermination方法
shutdownNow方法(发生异常或者是Timeout的时候)

实际开发的系统可能会有不能强制线程中止执行的场景出现,所以虽然推荐使用上面说的调用顺序但也并不是绝对一成不变的。

另外,可以经过一定时间间隔而有计划调用任务执行的ScheduledExecutorService同样适用于上面说的调用顺序,但是在使用scheduled方法的时候需要另外一些步骤。

猜你喜欢

转载自www.cnblogs.com/heroinss/p/9858552.html