<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题
一、 问题描述
先来看一下异常信息,启动tomcat时就报错:
- 2015-3-20 15:22:39 org.apache.catalina.core.StandardContext listenerStart
- 严重: Exception sending context initialized event to listener instance of class
- com.***.***.action.GateWayMonitorListener
- java.util.concurrent.RejectedExecutionException
- at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution
- (ThreadPoolExecutor.java:1774)
- at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.jav
- a:768)
- at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(Sched
- uledThreadPoolExecutor.java:215)
- at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleWithFixedDel
- ay(ScheduledThreadPoolExecutor.java:443)
- at com.***.***.action.GateWayMonitorListener
- .scheduleEmailAndSms(GateWayMonitorListener.java:77)
- at com.***.***.action.GateWayMonitorListener
- .contextInitialized(GateWayMonitorListener.java:67)
- at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
- t.java:4206)
- at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
- 705)
- at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
- .java:799)
- at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
- 9)
- at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
- at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.jav
- a:1079)
- at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.j
- ava:1002)
- at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:506
- )
- at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317)
- at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
- :324)
- at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
- eSupport.java:142)
- at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065)
- at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
- at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
- at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463
- )
- at org.apache.catalina.core.StandardService.start(StandardService.java:5
- 25)
- at org.apache.catalina.core.StandardServer.start(StandardServer.java:754
- )
- at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
- java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
- sorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:597)
- at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
- at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
- 2015-3-20 15:22:39 org.apache.catalina.core.StandardContext start
- 严重: Error listenerStart
再来看看相关源码:
- public class GateWayMonitorListener implements ServletContextListener, ApplicationContextAware
- {
- /**
- * 设定两个线程,一个用来定期发送巡检短信;另一个定期执行三大运营商网关监控。
- */
- public static ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
- public void contextInitialized(ServletContextEvent event)
- {
- // 网关监测
- GateWayMonitorListener.service.scheduleWithFixedDelay(new MonitorTask(), 60, MonitorConfigCache.lastPollingIntervalSecond, TimeUnit.SECONDS);
- // 定时每天固定时间发送短信
- GateWayMonitorListener.service.scheduleAtFixedRate(new EveryDaySmsTask(), calculateIntialDelay(), GateWayMonitorListener.ONE_DAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
- }
- }
- /**
- * 按新时间间隔重新设置定时任务。
- *
- * @param interval
- */
- public static synchronized void resetMonitorTaskInterval()
- {
- // 关闭老的线程池
- GateWayMonitorListener.service.shutdownNow();
- try
- {
- GateWayMonitorListener.service.awaitTermination(60, TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- log.warn("InterruptedException when shutdown old threadPool", e);
- }
- catch (Exception e)
- {
- log.error("other exception when shutdown old threadPool", e);
- }
- GateWayMonitorListener.service = Executors.newScheduledThreadPool(2);
- // 重新设置定时任务。
- …
- }
没有列出的还有另一个类会定时重新加载定时任务的配置文件,如果配置文件修改了定时任务执行的时间设置,则重新配置定时任务,起到热加载配置文件的目的。也就是会调用resetMonitorTaskInterval()方法。
二、 问题分析
Tomcat一启动就报错RejectedExecutionException,
(1)根据jdk描述何时回抛出这个异常:if the task cannot be scheduled for execution,只是说任务在不能被加入线程池时会抛出这个异常,不够明确。
(2)进一步分析什么时候线程池不能加入线程来执行,如果不是线程池还未被初始化好,线程池已满且策略是超过的会被拒绝外,就是线程池被shutdown了。Tomcat一启动就报错,而且线程池是在最上面static的,那应该就是被shutdown了。查看是否有哪里调用shutdown方法了。
(3)再分析,果然在另一个线程处会调用重新设置线程池的方法resetMonitorTaskInterval(),而且里面调用了shutdown。问题找到了,第一次读配置文件时就触发了重新设置定时任务。这是不行滴。。第一次只算是初始化,后面发现变更才应该重设线程池。但一定要控制同步,保证shutdown之后没有再往旧线程池中加入定时任务。
三、 问题解决
控制线程池的shutdown调用,调用后不能再往线程池里加入线程。
原文地址:http://zoroeye.iteye.com/blog/2194390
<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题的更多相关文章
- 一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结
一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结 这是一个十分严重的线上问题 自从最近的某年某月某天起,线上服务开始变得不那么稳定(软病).在高峰期,时常有几台机器的 ...
- 【转】一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结
[转]原文链接:https://cloud.tencent.com/developer/article/1497826 这是一个十分严重的线上问题 自从最近的某年某月某天起,线上服务开始变得不那么稳定 ...
- JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理
本文记录: 1,使用ScheduledExecutorService的 scheduleAtFixedRate 方法执行周期性任务的过程,讨论了在任务周期执行过程中出现了异常,会导致周期任务失败. 2 ...
- JUC线程池之 线程池的5种状态:Running, SHUTDOWN, STOP, TIDYING, TERMINATED
线程池有5种状态:Running, SHUTDOWN, STOP, TIDYING, TERMINATED. 线程池状态定义代码如下: private final AtomicInteger ctl ...
- Java 线程池原理分析
1.简介 线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销.在应用上,线程池可应用在后端相关服务中.比如 Web 服务器,数据库服务器等 ...
- Java线程池原理解读
引言 引用自<阿里巴巴JAVA开发手册> [强制]线程资源必须通过线程池提供,不允许在应用中自行显式创建线程. 说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销 ...
- Java线程池基础
目录: 一.线程池概述 二.线程池参数 三.线程池的执行过程 四.线程池的主要实现 五.线程池的使用 六.线程池的正确关闭方式 七.线程池参数调优 一.线程池概述 1.线程池类 目前线程池类一般有两个 ...
- 线程池 | Java多线程,彻底搞懂线程池
熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了. 最近看了一些相关文章,并亲自研究了一下源码,发现有些文章还是有些问题的,所以我也总结了 ...
- Java并发指南12:深度解读 java 线程池设计思想及源码实现
深度解读 java 线程池设计思想及源码实现 转自 https://javadoop.com/2017/09/05/java-thread-pool/hmsr=toutiao.io&utm_ ...
随机推荐
- python+appium+PyCharm==自动化测试APP环境
1.点击SDK下面的uiautomatorviewer 2.启动夜神3.启动adb--->在cmd adb -version adb connect 127.0.0.1:62001 这里的配置环 ...
- js跨域需要token。
将rems从tms中独立出来以后,每次都需要先打开tms,再打开rems,如果我足够聪明,那么很容易可以分析得到原因. 第一,会导致跨域出现问题的易错点就那么几个,是否加上“Access-Contro ...
- struts2实现jQuery的异步交互
struts2中jQuery的异步交互有两种方式: 1)是利用构造字符串的方式来实现: 使用该方法主要是在服务器端根据前端的请求,返回一个字符串信息,然后前端的jQuery通过解析该字符串信息得到对应 ...
- 关于c语言中的program_invocation_short_name
错误源自用g++的交叉编译工具链编译eudev.经过一番查找,发现在 errno.h 这个头文件中有 program_invocation_short_name 的 extern 定义. 经过查看 e ...
- Attention Is All You Need 一些好的资料
The encoders are all identical in structure (yet they do not share weights). Each one is broken down ...
- python2.7之乱码问题
python 3之后当然不存在乱码问题了.python 2的乱码问题有时就有点头疼了.(代码均为在windows下测试) 示例:保存为test1.py 报错信息如下: 解决办法: 我将代码保存为tes ...
- SolidWorks242个使用技巧
1 您可以使用 CTRL+TAB 键循环进入在 SolidWorks 中打开的文件. 2 使用方向键可以旋转模型.按 CTRL 键加上方向键可以移动模型.按 ALT 键加上方向键可以将模型沿顺时针或逆 ...
- 特征点方法 - Harris和SURF的手工实现
整理去年做的小项目,纪念我的图像处理入门. 因为要在DSP上实现,所以完全手工C代码垒起来的,还要保证和PC端跑的结果一样,觉得可能特殊场景会有用,上传github,没有依赖任何库: 格式注释什么的暂 ...
- Linux基础命令---显示登录用户w
w 显示哪些用户登录,并且显示用户在干什么.报头按此顺序显示当前时间.系统运行时间.当前登录用户数以及过去1.5和15分钟的系统平均负载.接着为每个用户显示以下条目:登录名.TTY名称.远程主机.登录 ...
- Android百大框架排行榜
Android百大框架排行榜 15类Android通用流行框架 - 流风,飘然的风 - 博客园https://www.cnblogs.com/zdz8207/p/android-opensource- ...