- 浏览: 496874 次
- 性别:
- 来自: OnePiece
文章分类
- 全部博客 (196)
- --------- 基础----------- (0)
- java 碎碎念 (12)
- java 并行编程 (11)
- java I/O (6)
- java Charset & Encoding (2)
- spring学习笔记 (8)
- 正则表达式 (5)
- web前端-javascript (11)
- web前端-jQuery (7)
- web前端-碎碎念 (1)
- mybatis (0)
- 数据库-通用 (8)
- 数据库-oracle (20)
- nosql-redis (11)
- nosql-mongoDB (1)
- xml (2)
- log4j (2)
- uml (3)
- web services: soap/wsdl (6)
- soa-tuscany (2)
- linux (6)
- ----------修养----------- (0)
- 深入理解java虚拟机 (7)
- java 设计模式 (9)
- 数据结构和算法 (2)
- 读书笔记--代码整洁之道 (2)
- 计算机基础 (1)
- -----------践行---------- (0)
- 重构(refactor) (7)
- jvm-诊断 (4)
- 数据库-让oracle跑得更快 (7)
- Nginx (6)
- ehcache (2)
- 短信开发 (1)
- Servlet+Filter+Listener (2)
- 运维 (6)
- 问题记录 (38)
- 杂七杂八 (12)
最新评论
-
zhanggang807:
第二种方法比较好
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext() -
assasszt:
谢谢分享,很清楚的讲明了原理。
字符集与字符编码简介 -
su0nils000:
难得的笔记
<进阶-2> 打造高效正则表达式 -
足至迹留:
mini188 写道用MD5来解决碰撞是不是也是可行的呢?个人 ...
Hash简介 -
mini188:
用MD5来解决碰撞是不是也是可行的呢?
Hash简介
<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题
一、 问题描述
先来看一下异常信息,启动tomcat时就报错:
再来看看相关源码:
没有列出的还有另一个类会定时重新加载定时任务的配置文件,如果配置文件修改了定时任务执行的时间设置,则重新配置定时任务,起到热加载配置文件的目的。也就是会调用resetMonitorTaskInterval()方法。
二、 问题分析
Tomcat一启动就报错RejectedExecutionException,
(1)根据jdk描述何时回抛出这个异常:if the task cannot be scheduled for execution,只是说任务在不能被加入线程池时会抛出这个异常,不够明确。
(2)进一步分析什么时候线程池不能加入线程来执行,如果不是线程池还未被初始化好,线程池已满且策略是超过的会被拒绝外,就是线程池被shutdown了。Tomcat一启动就报错,而且线程池是在最上面static的,那应该就是被shutdown了。查看是否有哪里调用shutdown方法了。
(3)再分析,果然在另一个线程处会调用重新设置线程池的方法resetMonitorTaskInterval(),而且里面调用了shutdown。问题找到了,第一次读配置文件时就触发了重新设置定时任务。这是不行滴。。第一次只算是初始化,后面发现变更才应该重设线程池。但一定要控制同步,保证shutdown之后没有再往旧线程池中加入定时任务。
三、 问题解决
控制线程池的shutdown调用,调用后不能再往线程池里加入线程。
先来看一下异常信息,启动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调用,调用后不能再往线程池里加入线程。
发表评论
-
修改第三方源码并重新打包
2017-02-14 17:05 29601.场景 很多时候需要下载第三方源码修改并重新编译打包,比如m ... -
内部类引发的cglib创建失败
2016-11-22 14:48 15571. 问题描述 使用cglib库 ... -
super用在了匿名内部类里
2016-07-06 09:47 12901.问题描述 本来是重构时在父类里增加了一个protected ... -
<spring-expected at least 1 matching bean> 缺少bean定义
2016-03-04 10:37 14561. 问题描述 ... Error creating bean ... -
《IDEA 循环依赖》Annotation processing is not supported for module cycles.
2015-11-04 16:30 371771. 错误现象 Error:java: Annotation ... -
数据库小问题集合
2015-09-23 14:58 6971. mysql默认查询时,不区分字母大小写。 比如:sele ... -
slf4j 的MDC (附带主动获取方法堆栈)
2015-08-03 17:29 54031. 主动获取方法调用链 ... -
<spring-aop> BeanNotOfRequiredTypeException 切面异常
2015-07-24 17:59 67261. 问题描述 往工程里添加切面,定义了<aop:asp ... -
<Spring-Aspect> 切面类(@Aspect)首先必须是bean
2015-07-20 14:08 37331. 问题描述 今天发现老工程里有个日志切面但是总是也没有执行 ... -
<tomcat> 启动报错 Error listenerStart
2015-07-10 09:32 3418今天同事遇到一个tomcat启动失败的问题,日志信息很少,不知 ... -
Intellij IDEA--can't use subversion command line client : svn
2015-06-04 10:45 172511. 错误描述 初用IDEA,暂时感到的还是不适应。导入工程报 ... -
<myeclipse> 修改Source Folder
2015-04-27 16:25 1676MyEclipse工程里新增文件夹时有普通Folder和Sou ... -
<maven> 新工程打包遇到Access restriction
2015-04-27 16:17 11871、错误描述 Access restriction: The ... -
<windows, tomcat> tomcat安装为windows服务,查看windows服务器启动时间
2015-03-12 10:47 1652一、tomcat安装为windows服务 1.已经安装好的to ... -
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext()
2015-02-26 14:17 58141.问题描述 singleton的bean,spring配置定 ... -
<ajax> 给$.post()的回调方法传递多个参数
2015-01-16 14:10 38321.问题描述 想给$.post()的回调方法传递多个参数,如果 ... -
<js,jquery>正则表达式不需要用引号包围
2015-01-04 16:20 1126js或jquery里的正则表达式不能用"" ... -
<js,jquery> each里的continue和break效果
2015-01-04 16:17 753通常js或jquery里each比for用的更多,for循环里 ... -
chrome的粘贴带有样式
2014-12-28 22:02 12161.问题描述 页面div里的内容是带样式的,需要复制里面的纯文 ... -
<db> order by 时sqlserver认为null是最大值
2014-12-22 10:52 1210order by时sqlserver和oracle对null值 ...
相关推荐
在Web应用中,定时器通常会在Web服务器启动时一起启动,并在服务器关闭时随之销毁,以实现后台的定时操作。 如描述中所述,有两种常见的方式在Web环境中启动Java定时器: 1. **使用Servlet**: - 在`web.xml`中...
在Java Web开发中,我们经常需要在服务器启动时自动加载特定的Servlet,并让它们执行一些初始化操作或定时任务。这通常涉及到对Web应用的配置文件`web.xml`以及Servlet类本身的编程。以下将详细讲解如何实现这个功能...
根据提供的文件信息,本文将详细解析Java定时任务与Spring框架集成的相关知识点,包括如何在Spring环境中配置和管理定时任务。 ### Java定时任务简介 在Java中实现定时任务主要有以下几种方式: 1. **Timer和...
在Java中,我们可以利用`java.util.Timer`类和`java.util.TimerTask`类来实现简单的定时任务,但这种实现方式存在线程安全问题。在Web应用中,我们可以利用Servlet容器提供的特性来更优雅地处理定时任务,这就是描述...
### 分布式定时任务Quartz概述 在当前的IT环境中,定时任务的高效稳定执行对于很多业务至关重要。本文主要探讨如何使用Quartz作为分布式定时任务的解决方案,并且着重介绍了其在Spring框架下的集成与应用。 ### ...
此外,标签中的“timer”和“servlet定时器”都指的是这种通过Servlet实现的定时任务机制,而“ScheduledExecutorService”是Java并发库中另一种强大的定时任务工具,它可以提供更灵活的定时策略和线程池管理。...
在Spring框架中,定时任务和线程池是两个非常重要的组件,它们可以帮助我们实现高效的后台任务处理。这篇博文“Spring基于线程池的定时任务线程异常实践”深入探讨了如何在Spring中结合线程池来执行定时任务,并且...
- ScheduledExecutorService 提供了定时和周期性任务的执行能力。 了解并熟练掌握这些知识点,有助于编写高效、稳定的并发程序,合理利用系统资源,避免因线程过多导致的资源浪费和性能问题。在实现自己的线程池时...
要实现服务器定时向客户端发送数据,可以在WebSocket服务端点中使用`ScheduledExecutorService`来定期调用`session.getAsyncRemote().sendText()`方法。 ```java @OnOpen public void onOpen(Session session) { ...
Spring 框架是 Java 开发中的核心组件之一,它提供了丰富的功能,包括但不限于依赖注入、面向切面编程以及各种企业级服务。在本篇中,我们将深入探讨如何在 Spring 框架中实现定时任务功能,特别是使用 Spring MVC ...
- 如果定时任务执行过程中出现阻塞,例如因为调试或者异常情况,那么同一线程池中的其他任务将被阻塞,直到阻塞任务完成。默认情况下,Spring Task使用的是单线程的ScheduledExecutorService,这意味着所有任务会...
2. **定时任务实现**:在`contextInitialized`方法中,我们可以启动一个定时任务,例如使用Java的`ScheduledExecutorService`或者Spring的`@Scheduled`注解。`ScheduledExecutorService`是Java并发库的一部分,可以...
在Spring框架中,定时任务是实现自动化操作的重要手段,它允许开发者在特定的时间间隔执行特定的任务,例如数据清理、报表生成等。在本实例中,我们关注的是Spring 3.0版本中的定时任务功能,这是一个基于Web工程的...
如果希望任务定期执行,而不是仅在启动时运行,还可以使用`ScheduledExecutorService`或者Spring框架的`@Scheduled`注解来创建更复杂的定时任务调度。 总结来说,Java定时执行可以通过多种方式实现,包括`java.util...
在定时任务方面,Spring 3.0提供了`org.springframework.scheduling`包,其中包括了`TaskScheduler`和`ScheduledExecutorService`接口,用于实现异步任务和定时任务。 然而,对于复杂的定时任务需求,Quartz 1.0则...
Java的ScheduledExecutorService提供了定时任务的支持,可以通过它的scheduleAtFixedRate()或scheduleWithFixedDelay()方法来安排周期性的任务。 在`hy.common.tpool`这个库中,可能包含了一套自定义的线程池实现,...
TaskExecutor接口是Spring提供的一个异步任务执行接口,它并不直接支持定时任务,但可以通过配合ScheduledExecutorService或者ThreadPoolTaskScheduler来实现定时任务。ScheduledExecutorService是Java的并发库提供...
Spring框架是Java开发中广泛使用的轻量级框架,它提供了许多功能,其中之一就是调度任务执行。Spring调度允许开发者安排一次性或周期性的任务执行,这对于实现后台服务、定时任务或者批处理作业非常有用。本篇文章将...
在Java中,我们可以使用内置的`java.util.Timer`类和`java.util.concurrent.ScheduledExecutorService`来实现定时任务。这两个工具提供了不同的调度策略,可以根据实际需求选择合适的。 1. `java.util.Timer` 和 `...
在Spring框架中,定时任务是通过Spring Task模块来实现的,它提供了强大的任务调度和执行功能,能够方便地实现应用程序中的周期性任务。本篇将详细介绍如何配置和使用Spring的定时器来定时调用任务。 首先,让我们...