zoukankan      html  css  js  c++  java
  • 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里,做为并发工具类被引进的,这是最理想的定时任务实现方式。

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

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

      可以很灵活的去设定第一次执行任务delay时间

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

    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内部也是依靠它实现的。示例代码:

    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接口包含唯一的方法:

    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);
        }
    }
  • 相关阅读:
    强制开启Android webview debug模式
    JavaScript DOM操作案例自定义属性的设置跟获取
    JavaScript innerText跟innerHTML的区别
    JavaScript DOM操作案例封装innerText跟textContent函数(浏览器兼容)
    JavaScript其他获取元素的方式
    JavaScript DOM操作案例根据类样式的名字获取元素
    JavaScript DOM操作案例根据name属性获取元素
    Java throws 使用
    理解 Android Build 系统
    理解Android编译命令
  • 原文地址:https://www.cnblogs.com/tanlei-sxs/p/10007620.html
Copyright © 2011-2022 走看看