跟着实例学习java多线程10

定时任务是我们经常遇到的业务场景,我们有很多的功能都需要这样的技术来实现,例如:定时获取一些数据push出去,定时处理一些清理任务,定时检查某个值等。那么我们该怎么实现,在实现中又该注意一些什么?

定时任务就是另开一个线程来执行,其实也是并发的一类,大家可能不好理解,说定时不就是到时间执行一下,怎么还会产生并发,这里主要是看两个指标,一是看执行频率,二是看每次执行的时间,如果执行频率高并且执行任务又会很耗时,那么这时候就形成了并发,当然还有一种情况那就是,定时的job中调用其它类的方法,而正常的业务逻辑中也调用那个类的方法,那么这时在某个巧合的时间也有可能对那个类的调用发生并发。

所以我们在写定时任务的时候也要注意这么两点:

1:如果执行频率高并且执行任务又会很耗时,要在job的执行方法上加同步处理。

2:如果job里调用其它类方法,那么其它类所提供的方法也要保证发布成线程安全的。

下面我们举例几种实现定时任务的方式:

1:java提供的timer

package com.home.thread.thread10;import java.util.Date;import java.util.Timer;/** * @author gaoxu * 实践出真知! */public class TimerMain {/** * @param args */public static void main(String[] args) {Timer timer = new Timer();timer.schedule(new TimerTaskThread(), new Date(), 2000);}}

package com.home.thread.thread10;import java.util.Date;import java.util.TimerTask;/** * @author gaoxu * 实践出真知! */public class TimerTaskThread extends TimerTask{//没有参数的构造函数public TimerTaskThread(){}//也可以写有参数的构造函数@Overridepublic synchronized void run() {System.out.println(new Date().toString()+"Timer方式,我是两秒执行一次");//这里可以写自己要实现的定时业务}}

这是一个由timer来实现的定时任务,运行结果如下:

Sat Feb 07 01:25:31 CST 2015,Timer方式,我是两秒执行一次Sat Feb 07 01:25:33 CST 2015,Timer方式,我是两秒执行一次Sat Feb 07 01:25:35 CST 2015,Timer方式,我是两秒执行一次Sat Feb 07 01:25:37 CST 2015,Timer方式,我是两秒执行一次

2:由开源框架Quartz实现的定时任务

package com.home.thread.thread10;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory;import com.home.JobServiceImpl;/** * @author gaoxu * 实践出真知! */public class SchedulerMain {public static void main(String[] para) {try {SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();JobServiceImpl jobService = new JobServiceImpl();jobService.setScheduler(scheduler);jobService.platDataCollectInterval(2);} catch (SchedulerException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

package com.home;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SimpleScheduleBuilder;import org.quartz.Trigger;import org.quartz.TriggerBuilder;import com.home.job.TestJob;/** * @author gaoxu * 实践出真知! */public class JobServiceImpl {private Scheduler scheduler;public void setScheduler(Scheduler scheduler) {this.scheduler = scheduler;}public Scheduler getScheduler() {return scheduler;}public void platDataCollectInterval(int interval)throws SchedulerException, Exception {System.out.println("update PlatDataCollect cycle start");JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity("testJob_1", "group_1").build();Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger_1", "group_1").withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(interval)).build();scheduler.scheduleJob(jobDetail, trigger);scheduler.start();}}

package com.home.job;import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class TestJob implements Job{@Overridepublic synchronized void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("test job date:" + new Date().toString());}}

这里有三个类,其中job类是任务的执行者,Scheduler是一个调度器,调度器中可以创建多个Trigger,每个Trigger可以执行一个job。

log4j:WARN No appenders could be found for logger (org.quartz.impl.StdSchedulerFactory).log4j:WARN Please initialize the log4j system properly.log4j:WARN See #noconfig for more info.update PlatDataCollect cycle starttest job date:Sat Feb 07 01:30:31 CST 2015test job date:Sat Feb 07 01:30:33 CST 2015test job date:Sat Feb 07 01:30:35 CST 2015test job date:Sat Feb 07 01:30:37 CST 2015

3:由线程来实现

package com.home.thread.thread10;/** * @author gaoxu * 实践出真知! */public class ThreadMain {public static void main(String[] para) {ThreadTask threadTask = new ThreadTask();threadTask.start();}}

package com.home.thread.thread10;import java.util.Date;public class ThreadTask extends Thread{public void run(){while(true){try {Thread.sleep(2000);System.out.println(new Date().toString()+"线程方式,我是两秒执行一次");//这里可以写自己要实现的定时业务} catch (InterruptedException e) {e.printStackTrace();}}}}比谁都感激这份“不能说出的爱”。

跟着实例学习java多线程10

相关文章:

你感兴趣的文章:

标签云: