springboot @Scheduled实现定时任务,@EnableAsync,@Async异步任务

实现定时任务的方式有如下几种,本文使用的是每3种

1、常见定时任务 Java自带的java.util.Timer类
            timer:配置比较麻烦,时间延后问题
            timertask:不推荐

2、Quartz框架
            配置更简单
            xml或者注解

3、SpringBoot使用注解方式开启定时任务
      1)启动类里面 @EnableScheduling开启定时任务,自动扫描
      2)定时任务业务类 加注解 @Component被容器扫描
      3)定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次

 

@Scheduled注解 参数详细说明
      crontab 工具  https://tool.lu/crontab/
1、cron 定时任务表达式 @Scheduled(cron="*/1 * * * * *") 表示每秒
2、fixedRate: 定时多久执行一次(上一次开始执行时间点后xx秒再次执行;)
3、fixedDelay: 上一次执行结束时间点后xx秒再次执行
4、fixedDelayString:  字符串形式,可以通过配置文件指定

定时任务示例代码,调用的代码省略了

import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TestTask {

	@Scheduled(fixedRateString="2000")//两秒执行一次
	//@Scheduled(cron="*/2 * * * * *")
	public void sum() throws InterruptedException{
		Thread.sleep(4000L);
		System.out.println("结束 当前时间:"+new Date());
	}

	//@Scheduled(cron="*/1 * * * * *")
	public void sum2(){
		System.out.println("cron 每秒 当前时间:"+new Date());
	}
}




异步任务使用的方法
1、启动类里面使用@EnableAsync注解开启功能,自动扫描

2、定义异步任务类并使用@Component标记组件被容器扫描,异步方法加上@Async
       注意点:
      1)要把异步任务封装到类里面,不能直接写到Controller
      2)增加Future 返回结果 AsyncResult("task执行完成");  
      3)如果需要拿到结果 需要判断全部的 task.isDone()

3、注意,一定要在Controller层调用测试

异步任务示例代码,任务类

import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

@Component
@Async //可放在类上,也可在方法上
public class AsyncTask {

	public void task1() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(1000L);
		long end = System.currentTimeMillis();
		System.out.println("任务1耗时="+(end-begin));
	}
	
	public void task2() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(2000L);
		long end = System.currentTimeMillis();
		System.out.println("任务2耗时="+(end-begin));
	}
	
	public void task3() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(3000L);
		long end = System.currentTimeMillis();
		System.out.println("任务3耗时="+(end-begin));
	}
	
	
	//获取异步结果
	public Future task4() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(2000L);
		long end = System.currentTimeMillis();
		System.out.println("任务4耗时="+(end-begin));
		return new AsyncResult("任务4");
	}
	
	
	public Future task5() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(3000L);
		long end = System.currentTimeMillis();
		System.out.println("任务5耗时="+(end-begin));
		return new AsyncResult("任务5");
	}
	
	public Future task6() throws InterruptedException{
		long begin = System.currentTimeMillis();
		Thread.sleep(1000L);
		long end = System.currentTimeMillis();
		System.out.println("任务6耗时="+(end-begin));
		return new AsyncResult("任务6");
	}

}

调用方法测试

import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1")
public class UserController {

	@Autowired
	private AsyncTask task;
	
	@GetMapping("async_task")
	public JsonData exeTask() throws InterruptedException{
		
		long begin = System.currentTimeMillis();
//异步任务		
//		task.task1();
//		task.task2();
//		task.task3();

//异步任务,有返回结果
		Future task4 = task.task4();
		Future task5 = task.task5();
		Future task6 = task.task6();
//无限循环,效率比while(true)快,因为while(true)每次循环要判断循环条件
		for(;;){
			if (task4.isDone() && task5.isDone() && task6.isDone()) {
				break;
			}
		}
		
		long end = System.currentTimeMillis();
		
		long total = end-begin;
		System.out.println("执行总耗时="+total);
		return JsonData.buildSuccess(total);
	}
}


运行结果,主任务主线程,运行的总时间,也就 3秒多点

 

你可能感兴趣的:(#,springboot)