`
heipark
  • 浏览: 2095149 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring quartz使用多线程并发“陷阱”

    博客分类:
  • Java
阅读更多

定义一个job:ranJob,设置每秒执行一次,设置不允许覆盖并发执行

 

	<bean id="rankJob" class="com.chinacache.www.logstat.job.RankJob" />
	<bean id="rankJobDetail"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="rankJob" />
		<property name="targetMethod" value="execute" />
		<property name="concurrent" value="false" />
	</bean>
	<bean id="rankJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail" ref="rankJobDetail" />
		<!-- 单位 ms,半小时 1800000 ms -->
		<property name="repeatInterval" value="1000" />
	</bean>

 

job代码:

		System.out.println("Start job");
		ExecutorService exec = Executors.newFixedThreadPool(1);
		
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("thread start");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("thread end");
			}
		});
		exec.execute(thread);
		System.out.println("end job");

 

程序输出结果:

Start job
end job
thread start
Start job
end job
thread start
Start job
end job
thread start
Start job
end job
thread start
thread end

 

从结果可以看到,job的并发覆盖配置似乎根本没有生效,原因是:job没有关注多线程执行情况

修改job代码,添加如下代码在job访问最后,线程处理完job才结束,

 

        while (!exec.isTerminated()) {
            // 等待所有子线程结束,才退出主线程
        }

 

修改代码后程序结果:

Start job
thread start
thread end

 

可以看到job始终没有结束,说明ExecutorService始终没有终止,看看文档,加入shutdonw()方法,job所有代码如下:

	public void execute() throws InterruptedException {
		System.out.println("Start job");
		ExecutorService exec = Executors.newFixedThreadPool(1);
		
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("thread start");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("thread end");
			}
		});
		exec.execute(thread);
		exec.shutdown();
        while (!exec.isTerminated()) {
            // 等待所有子线程结束,才退出主线程
        }		
		System.out.println("end job");
	}

 

打印结果如下:

 

Start job
thread start
thread end
end job

Start job
thread start
thread end
end job

Start job
thread start
thread end
end job

 

 

OK,至此spring quartz多线程并发问题解决。回顾下,我们要使用isTerminated()方法等多线程结束后在结束job;多线程任务派发结束后,要使用shutdown()方法顺序关闭线程(等待正在执行任务,不接受新任务)

分享到:
评论
1 楼 BigBird2012 2016-06-16  
想问一下,使用ExecutorService每次都要调用 shutdown?我的理解是给线程分配的任务执行完了线程就会释放,处于空闲状态,等待新的任务,shutdown 是不是将整个线程池关闭了呢?

相关推荐

    Spring Quartz1.8.x

    6. **并发和集群**:Quartz支持多线程和多服务器环境,Spring Quartz也继承了这一特性。通过集群配置,可以在多台服务器上共享任务调度,提高系统的可用性和可靠性。 7. **监控和管理**:Spring Quartz提供了Web...

    完美解决多应用服务器负载均衡环境下spring quartz同一定时任务重复执行问题

    在多应用服务器负载均衡环境下,Spring Quartz定时任务的重复执行问题是一个常见的挑战。Spring Quartz是一个强大的、开源的作业调度框架,允许开发者定义和执行复杂的定时任务。然而,当多个服务器实例并行运行时,...

    spring quartz 集群模式

    这里`myTargetObject`是一个bean引用,表示执行任务的目标对象,`executeTask`是该对象上的执行方法,`concurrent`属性决定是否允许多线程并发执行。 总结来说,Spring与Quartz的集群模式是通过共享数据库存储和...

    springquartz源码

    - **线程安全**:确保Job是线程安全的,因为Quartz可能并发执行多个Job实例。 - **资源管理**:合理配置ThreadPool大小,避免资源浪费。 通过以上知识点,我们可以看到Spring Quartz为Java开发人员提供了强大且...

    spring java 定时器 执行两次 quartz

    当我们遇到Spring定时器执行两次或者更多次的问题时,这通常是由于配置不当或者多线程并发导致的。下面将详细介绍如何使用Spring集成Quartz,以及解决定时任务重复执行的问题。 首先,让我们了解Spring如何配置...

    Spring quartz 定时任务调度

    Spring Quartz 还提供了一套机制来处理并发任务,如设置任务实例的并发策略,可以控制一个任务实例在同一时间只被一个线程执行,或者允许多个线程并行执行。 9. **任务持久化** Quartz支持任务和触发器的持久化...

    Spring的定时任务开发及对Quartz和Timer支持

    不过,由于Timer的线程模型存在一些限制,如所有定时任务都在同一个线程中运行,因此在多任务并发执行时可能会有性能问题。因此,对于复杂的定时任务需求,推荐使用Quartz这样的专业调度库。 Quartz与Spring的整合...

    Spring 使用Timer quartz区别

    此外,Quartz 支持集群环境,可以在多个节点之间共享任务,提高系统的可用性和可靠性。 Spring 框架与这两个定时任务工具有很好的集成。对于`java.util.Timer`,Spring 提供了`org.springframework.scheduling....

    spring-context-support-4.2.2和quartz-2.2.3所需Jar包

    2. **多线程与并发**:Quartz能够处理多个线程和并发任务,确保高效率和可靠性。 3. **持久化**:支持多种数据存储机制,如JDBC、RAMJobStore、RAMTriggerStore等,确保在系统重启后仍能恢复作业状态。 4. **插件...

    HttpClient+ Spring实现多线程

    标题 "HttpClient + Spring 实现多线程" 涉及到的是如何在Spring框架中使用Apache HttpClient库来创建一个支持多线程的HTTP客户端服务。Apache HttpClient是一个强大的HTTP客户端API,它提供了丰富的功能来处理HTTP...

    spring2.0 job Quartz 和Time一样的定时任务

    而Spring和Quartz设计时考虑了多线程和并发,更适合企业级应用。 4. 故障恢复:Quartz具有故障恢复和集群支持,如果任务执行失败,它可以重新安排任务执行,而Spring 2.0的`Job`则需要额外的代码来实现类似功能。 ...

    Spring Quatz 书-Quartz.Job.Scheduling.Framework.Building

    4. **并发和线程管理**:Quartz支持多线程执行,书中会讲解如何处理并发问题,例如避免多个实例同时执行同一作业,以及如何调整线程池大小以优化性能。 5. **日志和监控**:学习如何集成日志框架,以便记录作业执行...

    Quartz注入Spring的Bean

    2. **线程安全**:当多个Job实例并行运行时,确保注入的Bean是线程安全的,或者对并发访问进行了适当的同步控制。 3. **Job实例复用**:Quartz允许Job实例的复用,因此要确保Job类的状态不会在不同调度之间互相干扰...

    Spring的quartz和Timer实现定时

    总结来说,如果你需要一个强大的、可配置的、多线程的任务调度系统,Quartz是更好的选择;而如果任务需求简单,`Timer`则能满足基本需求。在Spring中,两者都可以方便地集成,根据项目的需求选择合适的工具是非常...

    Quartz和Spring整合

    - 任务并发执行:Quartz默认情况下,同一Job实例可能会被多个线程同时执行,这可能导致数据不一致。可以通过设置Job的`concurrency`属性为`false`,确保任务的串行执行。 - 事务管理:由于Quartz并不内置事务支持,...

    springboot的schedule和quartz到底怎么选以及如何支持并发和避坑

    当涉及到并发支持时,`@Scheduled`默认是单线程执行,如果需要并发执行任务,可以通过设置`concurrentTasksScheduler`属性为true来启用多线程。而Quartz则允许在配置中指定每个Job实例的并发策略,比如单实例(不...

    spring+quartz

    - **线程安全**:确保 Job 代码是线程安全的,因为 Quartz 默认会并发执行多个实例。 综上所述,Spring 和 Quartz 的结合使用为 Java 应用提供了强大而灵活的任务调度能力。通过 Spring 的管理,我们可以更轻松地...

    Spring支持的Quartz程序调度

    Spring框架是Java开发中广泛使用的应用框架,而Quartz则是一个功能强大的作业调度库,能够帮助开发者在应用程序中实现定时任务的安排。本篇文章将深入探讨Spring如何与Quartz集成,以及它们之间的协同工作原理。 ...

    多线程精品资源--novel 是一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发.zip

    -novel”表明这是一个关于多线程编程的高质量学习资料,结合“基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发”,我们可以推断出这是一套综合了后端与前端开发的教程,主要聚焦在Java的并发处理上,同时利用...

    结合spring和quartz实现定时生成网站主要的静态页面

    例如,可以使用多线程并行生成,以提高效率;同时,确保在生成静态页面时,动态内容的缓存能够及时更新。 总之,通过Spring和Quartz的组合,我们可以实现自动化、定时生成网站的静态页面,从而提升网站性能和用户...

Global site tag (gtag.js) - Google Analytics