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

  1. <bean id="rankJob" class="com.chinacache.www.logstat.job.RankJob" />
  2. <bean id="rankJobDetail"
  3. class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  4. <property name="targetObject" ref="rankJob" />
  5. <property name="targetMethod" value="execute" />
  6. <property name="concurrent" value="<span style="color: #ff0000;"><strong>false</strong></span>" />
  7. </bean>
  8. <bean id="rankJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
  9. <property name="jobDetail" ref="rankJobDetail" />
  10. <!-- 单位 ms,半小时 1800000 ms -->
  11. <property name="repeatInterval" value="<span style="color: #ff0000;"><strong>1000</strong></span>" />
  12. </bean>

job代码:

  1. System.out.println("Start job");
  2. ExecutorService exec = Executors.newFixedThreadPool(1);
  3. Thread thread = new Thread(new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("thread start");
  7. try {
  8. Thread.sleep(3000);
  9. } catch (InterruptedException e) {
  10. // TODO Auto-generated catch block
  11. e.printStackTrace();
  12. }
  13. System.out.println("thread end");
  14. }
  15. });
  16. exec.execute(thread);
  17. System.out.println("end job");

程序输出结果:

  1. Start job
  2. end job
  3. <span style="color: #ff0000;"><strong>thread start</strong></span>
  4. Start job
  5. end job
  6. thread start
  7. Start job
  8. end job
  9. thread start
  10. Start job
  11. end job
  12. thread start
  13. <strong><span style="color: #ff0000;">thread end</span></strong>

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

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

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

修改代码后程序结果:

  1. Start job
  2. thread start
  3. thread end

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

  1. public void execute() throws InterruptedException {
  2. System.out.println("Start job");
  3. ExecutorService exec = Executors.newFixedThreadPool(1);
  4. Thread thread = new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. System.out.println("thread start");
  8. try {
  9. Thread.sleep(3000);
  10. } catch (InterruptedException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. System.out.println("thread end");
  15. }
  16. });
  17. exec.execute(thread);
  18. exec.shutdown();
  19. while (!exec.isTerminated()) {
  20. // 等待所有子线程结束,才退出主线程
  21. }
  22. System.out.println("end job");
  23. }

打印结果如下:

  1. Start job
  2. thread start
  3. thread end
  4. end job
  5. Start job
  6. thread start
  7. thread end
  8. end job
  9. Start job
  10. thread start
  11. thread end
  12. end job

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

spring quartz使用多线程并发“陷阱”的更多相关文章

  1. spring quartz 配置

    quartz简介 各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务.任务调度本身涉及到多线程 ...

  2. Spring Quartz 和 Spring Task使用比较

    Quartz 和 Spring Task执行时间对比: 1. Quartz同步模式:一个任务的两次执行的时间间隔是:“执行时间”和“trigger的设定间隔”的最大值 2. Task默认同步模式:一个 ...

  3. Spring Quartz实现任务调度

    任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...

  4. 基于spring+quartz的分布式定时任务框架

    问题背景 我公司是一个快速发展的创业公司,目前有200人,主要业务是旅游和酒店相关的,应用迭代更新周期比较快,因此,开发人员花费了更多的时间去更=跟上迭代的步伐,而缺乏了对整个系统的把控 没有集群之前 ...

  5. Spring+quartz 实现定时任务job集群配置

    为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...

  6. JavaEE开发之Spring中的多线程编程以及任务定时器详解

    上篇博客我们详细的聊了Spring中的事件的发送和监听,也就是常说的广播或者通知一类的东西,详情请移步于<JavaEE开发之Spring中的事件发送与监听以及使用@Profile进行环境切换&g ...

  7. Spring+quartz 实现定时任务job集群配置【原】

    为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...

  8. Spring+Quartz 实现定时任务的配置方法

    Spring+Quartz 实现定时任务的配置方法 整体介绍 一.Quartz介绍 在企业应用中,我们经常会碰到时间任务调度的需求,比如每天凌晨生成前天报表,每小时生成一次汇总数据等等.Quartz是 ...

  9. Spring+Quartz 集群

    这几天给Spring+Quartz的集群折腾得死去活来,google了无数页总算搞定,记下一些要点备以后使用. 单独的Quartz集群在http://unmi.blogjava.net/有Unmi翻译 ...

随机推荐

  1. UVA 11584 - Partitioning by Palindromes DP

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  2. 获取iOS顶部状态栏和Navigation的高度

    状态栏的高度 20 [[UIApplication sharedApplication] statusBarFrame].size.height Navigation的高度 44 self.navig ...

  3. 关于Android中设置闹钟的相对比较完善的解决方案

    我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这里写的这个demo抽出来了封装了一个类库,大家直接调用其中的设置闹钟和取消闹钟的 ...

  4. 嵌入式arm linux环境中gdb+gdbserver调试

    一.前言嵌入式Linux系统中,应用开发过程中,很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序.采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采 ...

  5. LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its manifest, ntstatus 0xc0150002

    LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its mani ...

  6. 基于Android Fragment功能的样例

    通过近期空暇时候对Fragment的学习,尝试着写了一个小Demo,将在开发的时候能经常使用到的Fragment知识放在一起,写过了这个Demo对Android Fragment的了解更加深入了,以后 ...

  7. js进阶 12-4 jquery键盘事件如何使用

    js进阶 12-4 jquery键盘事件如何使用 一.总结 一句话总结:键盘和鼠标都是外设输入设备,所以函数很像,所以使用就像鼠标事件click一样 1.jquery键盘事件有哪三个? 1(up和do ...

  8. Python 奇葩语法

    a = 1, 2, 3 赋值后的结果,a == (1, 2, 3),将一个元组(tuple)赋给了变量 a (1, 2) + (3, ) ⇒ (1, 2, 3),并不能说明 tuple 可以添加新的元 ...

  9. window下利用navicat访问Linux下的mariadb数据库

    1.再Linux上成功安装mariadb数据库后,不管是在dos(敲命令mysql -h192.168.136.8 -uroot -p)下或者是navicat(创建连接)下连接mariadb数据库,会 ...

  10. JSP自己定义标签

    JSP自己定义标签 API文档: http://docs.oracle.com/javaee/7/api/ watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ ...