`
足至迹留
  • 浏览: 496874 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

<线程池-定时任务> 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调用,调用后不能再往线程池里加入线程。
0
0
分享到:
评论

相关推荐

    java定时器使用汇总.pdf

    在Web应用中,定时器通常会在Web服务器启动时一起启动,并在服务器关闭时随之销毁,以实现后台的定时操作。 如描述中所述,有两种常见的方式在Web环境中启动Java定时器: 1. **使用Servlet**: - 在`web.xml`中...

    JAVA项目服务器启动时自启动指定的Servlet,并定时执行任务

    在Java Web开发中,我们经常需要在服务器启动时自动加载特定的Servlet,并让它们执行一些初始化操作或定时任务。这通常涉及到对Web应用的配置文件`web.xml`以及Servlet类本身的编程。以下将详细讲解如何实现这个功能...

    java定时任务代码-spring管理.txt

    根据提供的文件信息,本文将详细解析Java定时任务与Spring框架集成的相关知识点,包括如何在Spring环境中配置和管理定时任务。 ### Java定时任务简介 在Java中实现定时任务主要有以下几种方式: 1. **Timer和...

    java轻松实现—定时任务

    在Java中,我们可以利用`java.util.Timer`类和`java.util.TimerTask`类来实现简单的定时任务,但这种实现方式存在线程安全问题。在Web应用中,我们可以利用Servlet容器提供的特性来更优雅地处理定时任务,这就是描述...

    quarz分布式定时任务

    ### 分布式定时任务Quartz概述 在当前的IT环境中,定时任务的高效稳定执行对于很多业务至关重要。本文主要探讨如何使用Quartz作为分布式定时任务的解决方案,并且着重介绍了其在Spring框架下的集成与应用。 ### ...

    Web Servlet定时器

    此外,标签中的“timer”和“servlet定时器”都指的是这种通过Servlet实现的定时任务机制,而“ScheduledExecutorService”是Java并发库中另一种强大的定时任务工具,它可以提供更灵活的定时策略和线程池管理。...

    Spring基于线程池的定时任务线挰异常实践

    在Spring框架中,定时任务和线程池是两个非常重要的组件,它们可以帮助我们实现高效的后台任务处理。这篇博文“Spring基于线程池的定时任务线程异常实践”深入探讨了如何在Spring中结合线程池来执行定时任务,并且...

    徒手实现线程池-1

    - ScheduledExecutorService 提供了定时和周期性任务的执行能力。 了解并熟练掌握这些知识点,有助于编写高效、稳定的并发程序,合理利用系统资源,避免因线程过多导致的资源浪费和性能问题。在实现自己的线程池时...

    WebSocket.zip

    要实现服务器定时向客户端发送数据,可以在WebSocket服务端点中使用`ScheduledExecutorService`来定期调用`session.getAsyncRemote().sendText()`方法。 ```java @OnOpen public void onOpen(Session session) { ...

    spring定时器实现源码

    Spring 框架是 Java 开发中的核心组件之一,它提供了丰富的功能,包括但不限于依赖注入、面向切面编程以及各种企业级服务。在本篇中,我们将深入探讨如何在 Spring 框架中实现定时任务功能,特别是使用 Spring MVC ...

    Spring框架-SpringBoot-定时任务-深入教程.pdf

    - 如果定时任务执行过程中出现阻塞,例如因为调试或者异常情况,那么同一线程池中的其他任务将被阻塞,直到阻塞任务完成。默认情况下,Spring Task使用的是单线程的ScheduledExecutorService,这意味着所有任务会...

    java web使用监听器实现定时周期性执行任务demo

    2. **定时任务实现**:在`contextInitialized`方法中,我们可以启动一个定时任务,例如使用Java的`ScheduledExecutorService`或者Spring的`@Scheduled`注解。`ScheduledExecutorService`是Java并发库的一部分,可以...

    Spring3.0定时任务简单实例web工程

    在Spring框架中,定时任务是实现自动化操作的重要手段,它允许开发者在特定的时间间隔执行特定的任务,例如数据清理、报表生成等。在本实例中,我们关注的是Spring 3.0版本中的定时任务功能,这是一个基于Web工程的...

    JAVA定时执行

    如果希望任务定期执行,而不是仅在启动时运行,还可以使用`ScheduledExecutorService`或者Spring框架的`@Scheduled`注解来创建更复杂的定时任务调度。 总结来说,Java定时执行可以通过多种方式实现,包括`java.util...

    定时器集成包

    在定时任务方面,Spring 3.0提供了`org.springframework.scheduling`包,其中包括了`TaskScheduler`和`ScheduledExecutorService`接口,用于实现异步任务和定时任务。 然而,对于复杂的定时任务需求,Quartz 1.0则...

    线程池、任务、任务组、任务池,定时任务的类库-hy.common.tpool.zip

    Java的ScheduledExecutorService提供了定时任务的支持,可以通过它的scheduleAtFixedRate()或scheduleWithFixedDelay()方法来安排周期性的任务。 在`hy.common.tpool`这个库中,可能包含了一套自定义的线程池实现,...

    Spring 定时任务源码(spring 三种定时任务的实现方式)

    TaskExecutor接口是Spring提供的一个异步任务执行接口,它并不直接支持定时任务,但可以通过配合ScheduledExecutorService或者ThreadPoolTaskScheduler来实现定时任务。ScheduledExecutorService是Java的并发库提供...

    使用spring调度

    Spring框架是Java开发中广泛使用的轻量级框架,它提供了许多功能,其中之一就是调度任务执行。Spring调度允许开发者安排一次性或周期性的任务执行,这对于实现后台服务、定时任务或者批处理作业非常有用。本篇文章将...

    java 定时任务及jar包

    在Java中,我们可以使用内置的`java.util.Timer`类和`java.util.concurrent.ScheduledExecutorService`来实现定时任务。这两个工具提供了不同的调度策略,可以根据实际需求选择合适的。 1. `java.util.Timer` 和 `...

    spring定时器,定时调用任务配置

    在Spring框架中,定时任务是通过Spring Task模块来实现的,它提供了强大的任务调度和执行功能,能够方便地实现应用程序中的周期性任务。本篇将详细介绍如何配置和使用Spring的定时器来定时调用任务。 首先,让我们...

Global site tag (gtag.js) - Google Analytics