java实现定时任务

普通thread--

 这是最多见的, 建立一个thread,而后让它在while循环里一直运行着,
 经过sleep方法来达到定时任务的效果。这样能够快速简单的实现,
package com.iotek.classtype; public class Task1 { public static void main(String[] args) { final long timeInterval=1000; Runnable runnable =new Runnable() { @Override public void run() { while(true) { System.out.println("hello !!!"); try { Thread.sleep(timeInterval); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } } } }; Thread thread=new Thread(runnable); thread.start(); } }

 

Timer类

Timer类能够调度任务,TimerTask则是经过在run()方法里实现具体任务。 Timer实例能够调度多任务,它是线程安全的。

 

 当Timer的构造器被调用时,它建立了一个线程,这个线程能够用来调度任务。 下面是代码:
经过
timer.schedule()方法
package com.iotek.classtype; import java.util.Timer; import java.util.TimerTask; public class Task2 { public static void main(String[] args) { TimerTask timerTask=new TimerTask() { @Override public void run() { System.out.println("HELLO"); } }; Timer timer=new Timer(); long delay=0; long intevalPeriod=1*1000; timer.schedule(timerTask, delay, intevalPeriod); } }

ScheduledExecutorService

ScheduledExecutorService是从Java SE5的java.util.concurrent里,作为并发工具类被引进的,这是最理想的定时任务实现方式。java

相比于上两个方法,它有如下好处:

  相比于Timer的单线程,它是经过线程池的方式来执行任务的web

  能够很灵活的去设定第一次执行任务delay时间spring

  提供了良好的约定,以便设定执行的时间间隔安全

package com.iotek.classtype; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Task3 { public static void main(String[] args) { Runnable runnable=new Runnable() { @Override public void run() { System.out.println("hello"); } }; ScheduledExecutorService service=Executors.newSingleThreadScheduledExecutor(); service.scheduleAtFixedRate(runnable, 10,1,TimeUnit.SECONDS); } }

JAVA实现定时任务的几种方式

  • JDK 自带的定时器实现

Timer类 
这个类容许你调度一个java.util.TimerTask任务。主要有如下几个方法:并发

//schedule(TimerTask task, long delay) 延迟 delay 毫秒 执行
   public static void main(String[] args) { for(int i=0;i<10;i++) { new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" run"); } }, 1000); }
View Code
//schedule(TimerTask task, Date time) 特定时间执行
    public static void main(String[] args) { for (int i = 0; i <20; i++) { new Timer("TIMER"+i).schedule(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" RUN"); } }, new Date(System.currentTimeMillis()+2000)); } }
View Code
//schedule(TimerTask task, long delay, long period) 延迟 delay 执行并每隔period 执行一次
    public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Timer(" timer"+i).scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"run"); } }, 1000, 2000); } }
View Code

ScheduledExecutorService 接口实现类 
ScheduledExecutorService 是JAVA 1.5 后新增的定时任务接口,主要有如下几个方法。框架

ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
 ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit);
 ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnitunit);
 ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnitunit);

默认实现为ScheduledThreadPoolExecutor 继承了ThreadPoolExecutor 的线程池特性,配合future特性,比Timer更强大。 具体用法能够阅读JDK文档;spring Task内部也是依靠它实现的。示例代码:maven

public static void main(String[] args) { ScheduledExecutorService service=Executors.newSingleThreadScheduledExecutor(); for (int i = 0; i < 10; i++) { service.schedule(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " run "); } }, 2, TimeUnit.SECONDS); } service.shutdown(); }
View Code
  • Quartz 定时器实现

Quartz是一个彻底由Java编写的开源做业调度框架,为在Java应用程序中进行做业调度提供了简单却强大的机制。Quartz容许开发人员根据时间间隔来调度做业。它实现了做业和触发器的多对多的关系,还能把多个做业与不一样的触发器关联。能够动态的添加删除定时任务,另外很好的支撑集群调度。简单地建立一个org.quarz.Job接口的Java类,Job接口包含惟一的方法:ide

public void execute(JobExecutionContext context) throws JobExecutionException;

在Job接口实现类里面,添加须要的逻辑到execute()方法中。配置好Job实现类并设定好调度时间表(Trigger),Quartz就会自动在设定的时间调度做业执行execute()。工具

整合了Quartz的应用程序能够重用不一样事件的做业,还能够为一个事件组合多个做业。Quartz经过属性文件来配置JDBC事务的数据源、全局做业、触发器侦听器、插件、线程池等等。(quartz.properties)学习

经过maven引入依赖(这里主要介绍2.3.0) 注意:shiro-scheduler中依赖的是1.x版本 若是同时使用会冲突

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

建立Job类

public class TestJob implements Job{
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());
    }
}

调度任务

public static void main(String[] args) throws InterruptedException, SchedulerException {

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        // 开始
        scheduler.start();
        // job 惟一标识 test.test-1
        JobKey jobKey = new JobKey("test" , "test-1");
        JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("test" , "test")
                // 延迟一秒执行
                .startAt(new Date(System.currentTimeMillis() + 1000))
                // 每隔一秒执行 并一直重复
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
                .build();
        scheduler.scheduleJob(jobDetail , trigger);

        Thread.sleep(5000);
        // 删除job
        scheduler.deleteJob(jobKey);
    }

关于简单使用,能够参考quartz的example,下面连接是一些入门帮助。

Quartz定时任务学习(一)简单任务 
Quartz定时任务学习(二)web应用 
Quartz定时任务学习(三)属性文件和jar

深刻学习能够阅读官方文档和相关博客阅读 
如下为推荐博客地址 
quartz详解2:quartz由浅入深  

  • Spring 相关的任务调度

Spring 3.0+ 自带的任务调度实现,主要依靠TaskScheduler接口的几个实现类实现。删除和修改任务比较麻烦。 
主要用法有如下三种: 

    • Spring配置文件实现
    • 注解实现
    • 代码动态添加
配置文件实现

 

spring-schedule.xml

<task:scheduler id="myScheduler" pool-size="10" />
<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="job" method="test" cron="0 * * * * ?"/>
</task:scheduled-tasks>

 

注解实现  

 

spring-schedule.xml
<task:scheduler id="myScheduler" pool-size="10" />
// 启用注解
<task:annotation-driven scheduler="myScheduler"/>

 

@Component  
public class Task{  

       @Scheduled(cron="0/5 * *  * * ? ")   //每5秒执行一次       
       public void execute(){     
             DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
             System.out.println(sdf.format(DateTime.now().toDate())+"*********B任务每5秒执行一次进入测试");      
       }      
}

 代码动态添加 

spring-schedule.xml

<bean id = "myScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
        <property name="poolSize" value="10"/>
        <property name="threadGroupName" value="myScheduler" />
        <property name="threadNamePrefix" value="-1" />
</bean>
<task:annotation-driven scheduler="myScheduler"/>
@Component
public class Test {

    @Autowired
    private ThreadPoolTaskScheduler myScheduler;

    public void addJob(){

        myScheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " run ");
            }
        } , new CronTrigger("0/5 * *  * * ? ")); //每5秒执行一次
    }
}

spring 结合 quartz 实现任务调度 

    • spring 配置文件 spring-quartz.xml

 

<bean id="quartzsScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
        <property name="triggers">
            <list>
            <ref bean="testTrigger" />
            </list>
        </property>
</bean>

<!-- jobClass须要继承QuartzJobBean  也可使用 MethodInvokingJobDetailFactoryBean 定义任意类任意方法为Job-->
<bean id="testJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
              <property name="jobClass">
                     <value>com.test.TestJob</value>
              </property>
              <property name="durability" value="true" />
              <!-- requestsRecovery属性必须设置为 true,当Quartz服务被停止后,再次启动或集群中其余机器接手任务时会尝试恢复执行以前未完成的全部任务 -->
              <property name="requestsRecovery" value="true" />
</bean>
<bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
              <property name="jobDetail" ref="testJobDetail" />
              <property name="cronExpression" value="0 0 10 * * ?" />
</bean>

动态增长删除  

 

@Component
public class Test {

    @Autowired
    private SchedulerFactoryBean quartzScheduler;

    public void addJob() throws SchedulerException {

        Scheduler scheduler = quartzScheduler.getScheduler();
        JobKey jobKey = new JobKey("test", "test");
        if (scheduler.checkExists(jobKey)) {
            return;
        }
        JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test", "test")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever()).build();
        scheduler.scheduleJob(jobDetail, trigger);
    }
}
相关文章
相关标签/搜索