<线程池-定时任务> 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_ ...
随机推荐
- FluentScheduler:开源轻量级定时任务调度架构
安装:FluentScheduler Install-Package FluentScheduler 一.控制台中使用 using System; using System.Collections.G ...
- hibernate中configuration和配置文件笔记
hibernate的核心类和接口 Configuration类 作用:(1)读取hibernate.cfg.xml文件 (2)管理对象关系映射文件<mapping resource=" ...
- caffe的运行create_data.sh前对VOC2007图片格式的更改
运用caffe进行深度学习之前需要对图片进行预处理,将图片的大小,格式等进行修改 将300*300的图片改为256*256格式 则将以下参数改为: min_dim=256 max_dim=256 wi ...
- SQLConnect
SQLConnect 函数定义: 这个函数就是与数据库建立连接 SQLRETURN SQLConnect( SQLHDBC ConnectionHandle, SQLCHAR * Se ...
- C#基本知识零散总结
C#基本知识零散总结 类的属性:(property) C#中定义属性使用的语法 public string SomeProperty { get { return "属性的值"; ...
- html5-块元素和内联元素
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- Pycharm学习python路
import 模块之后是灰色的表明没有被引用过 lxml找不到的话用anaconda prompt :pip uninstall lxml 重新安装 用request时,写的reg无法正确解析网页,先 ...
- 电脑已连接wifi的密码查询
有时候,想登陆自己家的无线网络(尤其朋友来家里突然要连接无线网络),脑子刹那间一片空白想不起来密码,怎么办呢? 其实,我们可以通过电脑来查看网络的密码,现在分享如何在笔记本电脑上查看连接过的无线网络密 ...
- 干货 | JavaScript内存空间详解
JS栈内存与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所以对于前端开发 ...
- Markdown编辑器使用说明
Markdown编辑器使用说明 #编辑器使用说明编辑器仅用来编辑文章的样式,建议在其他文档中写好内容,再复制到此处编辑样式--- ## 编辑器使用介绍—非开发者 非开发者,可以将编辑框内容全部删掉,使 ...