SpringBoot整合定时任务和异步任务处理

一、SpringBoot定时任务schedule

1)、启动类加注解@EnableScheduling开启定时任务,自动扫描

2)、定时任务业务类加注解@Component被容器扫描

3)、定时执行的方法加注解@Scheduled定期执行一次

@EnableScheduling // 开启定时任务
@SpringBootApplication
public class SpringBootTest2Application {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootTest2Application.class, args);
	}

}
// 定时任务业务类
@Component
public class TestTask {
	@Scheduled(fixedRate = 2000) // 两秒执行一次
	public void sum() {
		System.out.println("当前时间:" + new Date());
	}
}

二、常用定时任务配置实战

1)、cron定时任务表达式:@Scheduled(cron = “*/1 * * * * *”) 每秒执行一次

crontab工具:https://tool.lu/crontab/

2)、fixedRate:定时多久执行一次

@Component
public class TestTask {
	@Scheduled(fixedRate = 2000)
	public void sum() {
		System.out.println("开始的当前时间:" + new Date());
		try {
			TimeUnit.SECONDS.sleep(4);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("结束的当前时间:" + new Date());
	}
}

运行结果:

开始的当前时间:Mon Mar 04 16:39:24 CST 2019
结束的当前时间:Mon Mar 04 16:39:28 CST 2019
开始的当前时间:Mon Mar 04 16:39:28 CST 2019
结束的当前时间:Mon Mar 04 16:39:32 CST 2019
开始的当前时间:Mon Mar 04 16:39:32 CST 2019

使用fixedRate:如果上一个任务未执行完毕,需要等待上一个任务执行完才能执行下一个任务

3)、fixedDelay:上一次执行结束时间点后几秒再次执行

@Component
public class TestTask {
	@Scheduled(fixedDelay = 2000) 
	public void sum() {
		System.out.println("开始的当前时间:" + new Date());
		try {
			TimeUnit.SECONDS.sleep(4);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("结束的当前时间:" + new Date());
	}
}

运行结果:

开始的当前时间:Mon Mar 04 16:41:04 CST 2019
结束的当前时间:Mon Mar 04 16:41:08 CST 2019
开始的当前时间:Mon Mar 04 16:41:10 CST 2019
结束的当前时间:Mon Mar 04 16:41:14 CST 2019
开始的当前时间:Mon Mar 04 16:41:16 CST 2019

4)、fixedRateString和fixedDelayString:字符串形式,可以通过配置文件指定

三、SpringBoot整合异步任务

1)、启动类加注解@EnableAsync开启异步任务,自动扫描

2)、定义异步任务并使用@Component标记组件被容器扫描,异步方法加上@Async

注意点:

1)要把异步任务封装到类里面,不能直接写到Controller

2)增加Future<String>返回结果AsyncResult<String>("task执行完成")

3)如果需要拿到结果,需要判断全部的task.isDone()

3)、通过注入方式,注入到Controller里面,如果改为同步任务需要把@Async注释掉

4)、异步任务无返回结果

@EnableAsync //开启异步任务
@SpringBootApplication
public class SpringBootTest2Application {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootTest2Application.class, args);
	}

}
// 异步任务业务类
@Component
@Async
public class AsyncTask {

	public void task1() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(1);
		long end = System.currentTimeMillis();
		System.out.println("任务1耗时=" + (end - begin));
	}

	public void task2() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(2);
		long end = System.currentTimeMillis();
		System.out.println("任务2耗时=" + (end - begin));
	}

	public void task3() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(3);
		long end = System.currentTimeMillis();
		System.out.println("任务3耗时=" + (end - begin));
	}

}

测试类:

@RestController
@RequestMapping("/api/v1")
public class UserController {
	@Autowired
	private AsyncTask asyncTask;

	@RequestMapping("async_task")
	public String exeTask() throws InterruptedException {
		long begin = System.currentTimeMillis();
		asyncTask.task1();
		asyncTask.task2();
		asyncTask.task3();
		long end = System.currentTimeMillis();
		System.out.println("执行总耗时=" + (end - begin));
		return "success";
	}
}

运行结果:

执行总耗时=0
任务1耗时=1001
任务2耗时=2000
任务3耗时=3000

5)、异步任务存在返回结果

// 异步任务业务类
@Component
@Async
public class AsyncTask {

	public Future<String> task1() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(1);
		long end = System.currentTimeMillis();
		System.out.println("任务1耗时=" + (end - begin));
		return new AsyncResult<String>("任务1");
	}

	public Future<String> task2() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(2);
		long end = System.currentTimeMillis();
		System.out.println("任务2耗时=" + (end - begin));
		return new AsyncResult<String>("任务2");
	}

	public Future<String> task3() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(3);
		long end = System.currentTimeMillis();
		System.out.println("任务3耗时=" + (end - begin));
		return new AsyncResult<String>("任务3");
	}

}

测试类:

@RestController
@RequestMapping("/api/v1")
public class UserController {
	@Autowired
	private AsyncTask asyncTask;

	@RequestMapping("async_task")
	public String exeTask() throws InterruptedException {
		long begin = System.currentTimeMillis();
		Future<String> task1 = asyncTask.task1();
		Future<String> task2 = asyncTask.task2();
		Future<String> task3 = asyncTask.task3();
		for (;;) {
			if (task1.isDone() && task2.isDone() && task3.isDone()) {
				break;
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("执行总耗时=" + (end - begin));
		return "success";
	}
}

运行结果:

任务1耗时=1000
任务2耗时=2001
任务3耗时=3001
执行总耗时=3001

6)、去掉@Async改为同步任务

@Component
public class AsyncTask {

	public Future<String> task1() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(1);
		long end = System.currentTimeMillis();
		System.out.println("任务1耗时=" + (end - begin));
		return new AsyncResult<String>("任务1");
	}

	public Future<String> task2() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(2);
		long end = System.currentTimeMillis();
		System.out.println("任务2耗时=" + (end - begin));
		return new AsyncResult<String>("任务2");
	}

	public Future<String> task3() throws InterruptedException {
		long begin = System.currentTimeMillis();
		TimeUnit.SECONDS.sleep(3);
		long end = System.currentTimeMillis();
		System.out.println("任务3耗时=" + (end - begin));
		return new AsyncResult<String>("任务3");
	}

}

测试类同上

运行结果:

任务1耗时=1001
任务2耗时=2001
任务3耗时=3000
执行总耗时=6003
在Spring Boot中,可以使用@Scheduled注解来实现定时任务,可以结合@Async注解来实现多线程异步。 首先,需要在启动类上添加@EnableAsync注解,开启异步支持。然后在要执行异步任务的方法上添加@Async注解。 接下来,可以使用Java中的Executor框架来创建线程池,用于执行异步任务。可以在应用程序中创建一个线程池,并使用@Async注解将任务提交给线程池执行。 下面是一个示例代码: ```java @Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(30); executor.setThreadNamePrefix("MyAsyncThread-"); executor.initialize(); return executor; } } @Service public class MyService { @Async("taskExecutor") @Scheduled(cron = "0 0 12 * * ?") //每天中午12点执行 public void myAsyncTask() { //异步任务内容 } } ``` 在上面的示例中,我们创建了一个名为“taskExecutor”的线程池,并将其注入到MyService中的myAsyncTask方法中。该方法使用@Async注解来指示它应该在异步线程中执行。@Scheduled注解指定了任务执行的时间。 需要注意的是,@Async注解只有在调用该方法的类通过Spring容器进行管理时才会生效。如果通过new关键字手动创建对象,@Async注解将不起作用。 希望这可以帮助你完成Spring Boot定时任务整合多线程异步的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邋遢的流浪剑客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值