`
heipark
  • 浏览: 2077871 次
  • 性别: 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 是不是将整个线程池关闭了呢?

相关推荐

Global site tag (gtag.js) - Google Analytics