结论:Spring基于线程池的定时任务,线挰异常或内存溢出导致线程挂了,还会新启线程继续工作。
实例重现:
springMVC.properties
#the thread pool config thread.corePoolSize=3 thread.maxPoolSize=8 thread.keepAliveSeconds=6 thread.queueCapacity=2 timing.query.status.interval=3000
springMVC-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd "> <context:component-scan base-package="com.bijian.study"></context:component-scan> <!-- 系统配置文件 --> <context:property-placeholder location="classpath:springMVC.properties" /> <mvc:annotation-driven></mvc:annotation-driven> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数,默认为1 --> <property name="corePoolSize" value="${thread.corePoolSize}" /> <!-- 最大线程数,默认为Integer.MAX_VALUE --> <property name="maxPoolSize" value="${thread.maxPoolSize}" /> <!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE --> <property name="queueCapacity" value="${thread.queueCapacity}" /> <!-- 线程池维护线程所允许的空闲时间,默认为60s --> <property name="keepAliveSeconds" value="${thread.keepAliveSeconds}" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 --> <property name="rejectedExecutionHandler"> <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 --> <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 --> <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean> <task:scheduled-tasks> <!-- <task:scheduled ref="com.bijian.study.scheduled.TestScheduled" method="execute" cron="0 43 22 * * ?" /> --> <task:scheduled ref="com.bijian.study.scheduled.TestScheduled" method="execute" fixed-delay="${timing.query.status.interval}" /> </task:scheduled-tasks> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views" /> <property name="suffix" value=".jsp" /> </bean> </beans>
ScheduledService.java
package com.bijian.study.service; public interface ScheduledService { void noNormalTest(); void normalTest(); }
ScheduledServiceImpl.java
package com.bijian.study.service.impl; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import com.bijian.study.entity.Person; import com.bijian.study.service.ScheduledService; import com.bijian.study.util.JsonUtil; @Service("scheduledService") public class ScheduledServiceImpl implements ScheduledService { private static Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class); private static int COUNT = 0; @Override public void noNormalTest() { logger.info("entry ScheduledService noNormalTest:{}" ,"entry"); try { Thread.sleep(10000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { int j = 200/0; List<Person> personList = new ArrayList<Person>(3); personList.add(new Person("bijian", 10)); personList.add(new Person("lisi", 20)); personList.add(new Person("zhangshan", 30)); List<Person> personList2 = new ArrayList<Person>(); int i = 0; int count = personList.size(); while(i < count) { personList2.add(personList.get(i)); if(i == 2) { personList2.clear(); } } }catch(Exception e) { logger.error("noNormalTest Exception:{}", e); } logger.info("entry ScheduledService noNormalTest:{}" ,"exit"); } @Override public void normalTest() { logger.info("entry ScheduledService normalTest:{}" ,"entry"); // try { // //Thread.sleep(10000); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } if(COUNT++ == 0) { List<Person> personList = new ArrayList<Person>(); for(int i=0;i<1000000;i++) { personList.add(new Person("bijian", 10)); personList.add(new Person("lisi", 20)); personList.add(new Person("zhangshan", 30)); } logger.info("personList:{}", JsonUtil.toFullJson(personList)); } } }
BaseScheduled.java
package com.bijian.study.scheduled; public interface BaseScheduled { void execute(); }
TestScheduled.java
package com.bijian.study.scheduled; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import com.bijian.study.controller.HelloController; import com.bijian.study.service.ScheduledService; @Service(value = "com.bijian.study.scheduled.TestScheduled") public class TestScheduled implements BaseScheduled { private static Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired @Qualifier("taskExecutor") private ThreadPoolTaskExecutor threadPoolTaskExecutor; @Autowired private ScheduledService scheduledService; private static int COUNT = 0; @Override public void execute() { logger.info("enter TestScheduled"); if(0 == COUNT) { threadPoolTaskExecutor.execute(new Runnable() { @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } scheduledService.noNormalTest(); } }); }else { // class MyThread implements Runnable { // // private String name; // // public MyThread(String name) { // this.name = name; // } // // @Override // public void run() { //// try { // logger.info("MyThread name:{}", name); // try { // Thread.sleep(30000); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // scheduledService.normalTest(); //// }catch(Throwable e) { //// logger.info("exception:{}", e); //// } // } // } threadPoolTaskExecutor.execute(new Runnable() { @Override public void run() { scheduledService.normalTest(); } }); } COUNT ++; logger.info("exit TestScheduled"); } }
完整工程代码见附件《SpringMVC.zip》。
相关推荐
本文将基于Spring3.2.6版本,详细介绍如何配置线程池以及定时任务,并结合具体实例进行解析。 #### 二、Spring线程池配置 Spring框架提供了一个强大的任务调度模块,其中包含了对线程池的支持。下面通过一个具体的...
下面我们将深入探讨Spring的自带定时任务,包括基于注解和XML配置两种方式。 ### 1. Spring定时任务基础 Spring的定时任务功能是通过`org.springframework.scheduling`包中的类来实现的,主要涉及`TaskScheduler`...
Spring Task是在Spring 3.0之后引入的,它使用起来相对简单,支持线程池,可以高效处理不同的定时任务。Spring Task可以通过注解或XML配置文件来配置任务。如果使用注解的方式,仅需要在方法上加上@Scheduled注解,...
- `ThreadPoolTaskScheduler`:Spring提供的一个默认实现,基于线程池的任务调度器,可以控制并发执行的定时任务数量。 2. **Quartz Scheduler** - Quartz是一个开源的作业调度框架,可以实现复杂的时间规则和...
Spring提供了多种方式来创建和管理定时任务,包括基于接口的TaskExecutor、基于注解的@Scheduled和集成Quartz Scheduler。下面将详细讲解这三种定时任务的实现方式及其源码分析。 1. **基于TaskExecutor的定时任务*...
一个tomcat下部署了两个应用,一个是普通web应用syncc,另一个应用syncc_wx属于微信公众号后台程序涉及消息定时推送,tomcat未分离...”spring定时任务执行两次的异常排查处理.docx"针对上述描述问题进行分析和解决。
综上所述,Spring提供的定时任务功能使得开发者能够轻松地在非Web项目中实现复杂的时间驱动逻辑,无论是简单的定时执行还是基于Cron表达式的复杂调度,Spring都能提供强大的支持。通过合理配置和编程,我们可以创建...
在Java编程中,Spring框架提供了一种优雅的方式来管理和执行异步任务,这就是Spring的线程池。线程池是多线程编程中的一个重要概念,它能够有效地管理并发任务的执行,提高系统的性能和效率。本实例将深入探讨Spring...
1. Spring提供了一个名为ThreadPoolTaskExecutor的实现,它基于Java的ExecutorService接口,允许我们自定义线程池配置,如核心线程数、最大线程数、队列容量、超时时间等。 2. 通过在配置文件中声明一个...
在本实例中,我们关注的是Spring 3.0版本中的定时任务功能,这是一个基于Web工程的简单示例,适合在MyEclipse环境中运行。 首先,我们要了解Spring 3.0中的定时任务是如何工作的。Spring提供了`TaskExecutor`接口和...
其中,Spring的定时任务功能是许多项目中的重要组成部分,它允许开发者安排和执行周期性的任务。本文将详细探讨Spring定时任务的关键知识点,并与提供的jar包列表关联。 首先,Spring定时任务主要依赖于`spring-...
2.通过Spring是JAR-quartz写的一个定时任务 1)普通的定时任务,定时完成指定的任务 2)通过前台动态分配定时任务 可指定多个任务,可同时执行任务,可以精确到时分秒扫描并执行任务 3)可以完成稍微复杂点的任务 ...
基于Spring中的线程池和定时任务功能解析 Spring框架提供了线程池和定时任务执行的抽象接口:TaskExecutor和TaskScheduler来支持异步执行任务和定时执行任务功能。TaskExecutor是一个抽象接口,定义了execute方法,...
在Spring框架中,XML配置是传统且广泛使用的方式来设置应用的组件和行为,包括实现定时任务。定时任务在软件开发中扮演着重要角色,它允许应用程序在预设的时间执行特定的任务,例如数据清理、日志归档或者发送通知...
在Spring Boot应用中,定时任务是一项非常实用的功能,它允许我们按照预定的时间间隔执行特定的任务。Spring Boot提供了Spring Scheduler抽象来实现这样的需求,使得开发者能够方便地管理和控制定时任务。本篇文章将...
本项目采用`ThreadPoolTaskScheduler`来实现定时任务,这是一种基于Java线程池的定时任务调度器,相比Spring的`@Scheduled`注解,它提供了更灵活的配置和管理方式。 1. **ThreadPoolTaskScheduler介绍** `...
在Java Spring框架中,动态配置定时任务是一项非常实用的功能,它允许我们根据需求灵活地更改或添加定时任务,而无需每次改动都重启应用。本文将深入探讨如何在Spring中实现这种动态配置,以及如何结合数据库来管理...
它提供了基于`@Scheduled`注解和`TaskScheduler`接口的两种定时任务实现方式。`@Scheduled`适用于简单的定时任务,而`TaskScheduler`则更灵活,可以用于复杂的调度需求。 二、@Scheduled注解使用 1. 配置启用定时...