springboot开发系列-定时任务

168 阅读2分钟

一)注解式任务-单线程的

​
@Component
@EnableScheduling
public class ConacRecordTask {
    @Scheduled(cron="*/2 * * * * ?")
    public void task(){
        System.out.println("任务1");
    }
    @Scheduled(fixedRate=2000)
    public void task1(){
        System.out.println("任务2");
    }
}
​

@EnableScheduling:开启定时任务组件

@Component:我是一个组件

@Scheduled(cron="*/2 * * * * ?"):我是一个定时任务,我的规则是

定时任务执行的规则有很多种:

​
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String CRON_DISABLED = "-";
​
    String cron() default "";
​
    String zone() default "";
​
    long fixedDelay() default -1L;
​
    String fixedDelayString() default "";
​
    long fixedRate() default -1L;
​
    String fixedRateString() default "";
​
    long initialDelay() default -1L;
​
    String initialDelayString() default "";
}
​

一般是使用以下两种:

cron="*/2 * * * * ?" 依次代表:秒分时日月年
fixedRate=2000 上一次开始执行时间点之后多少毫秒再执行
fixedDelay = 1000 上一次执行完毕时间点之后多少毫秒再执行

也可以组合使用:

@Scheduled(initialDelay=2000, fixedRate=4000) :第一次延迟2秒后执行,第二次及以后每4秒执行一次

二)注解式任务-多线程异步处理

  1. 开始多线程任务

各个任务之间相互执行不受影响

​
@Component
@EnableScheduling//启用定时任务
@EnableAsync//开启多线程
public class ConacRecordTask {
    @Async//在Spring中,基于@Async标注的方法,称之为异步方法;这些方法在执行的时候,将会在独立的线程
    //中被执行,调用者无需等待它的完成,即可继续其他的操作。
    @Scheduled(cron="*/2 * * * * ?")
    public void task(){
        System.out.println("任务1"+Thread.currentThread().getName());
    }
    @Async
    @Scheduled(fixedRate=1000)
    public void task1(){
        System.out.println("任务2"+Thread.currentThread().getName());
    }
}
​

打印结果:

单线程任务1scheduling-1
任务1task-2
任务2task-3
单线程任务2scheduling-1
任务2task-4
单线程任务1scheduling-1
任务1task-5
任务2task-6
单线程任务2scheduling-1
任务2task-7

单线程的永远是一个线程在执行

2.如何获取异步方法的返回值:

使用Future的实现类AsyncResult来获取

代码如下:

    @Async
    @Scheduled(fixedRate = 2000)
    public Future<String> task3(){
        return new AsyncResult<>("我执行完了!");
    }
    @Async
    @Scheduled(fixedRate = 2000)
    public void task4(){
        AsyncResult asyncResult= (AsyncResult) task3();
        System.out.println("获取task3的执行结果:"+asyncResult.isDone());
    }

执行结果:

任务1task-5
任务2task-6
获取task3的执行结果:true
任务2task-1
任务1task-2
获取task3的执行结果:true

AsyncResult可以获取异步方法是否执行完,是否取消等状态

3.处理事物:

要将@Transactional的处理放到 @Async方法调用的方法中

这样组合使用是无法实现事物的

 @Async
 @Transactional
    @Scheduled(fixedRate = 2000)
    public Future<String> task3(){
        return new AsyncResult<>("我执行完了!");
    }

要使用这种方式:

@Async
    @Scheduled(fixedRate = 2000)
    public Future<String> task3(){
    tra();
        return new AsyncResult<>("我执行完了!");
    }
     @Transactional
     public static void tra(){
     //具体的事物
     }