SpringBoot异步处理任务

本文介绍了SpringBoot中同步和异步处理的概念,详细讲解了两种异步实现方式:使用线程池和SpringBoot的@Async注解。通过示例展示了如何通过线程池实现异步任务,以及启用@Async并定义异步方法来实现后台处理,从而提高应用程序的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

名词解释

1)同步:等用户所有操作结束后,才会返回程序的处理状态。

2)异步:直接返回给用户指定的状态,同时程序在后台继续运行,用户不用等待。

实现

同步实现

    @Autowired
	private TaskAsync taskAsync;

	/**
	 * 同步处理的方式
	 */
	@GetMapping("/test2")
	public String test2() {
		taskAsync.getTest2();
		System.out.println(Thread.currentThread().getName() + "==========主线程名");
		return "同步,正在解析......";
	}
@Component
public class TaskAsync {


	public void getTest2() {
		Building building = new Building();

		synchronized (building) {
			try {
				for (int i = 0; i <= 100; i++) {
					System.out.println(Thread.currentThread().getName() + "----------同步:>" + i);
					building.wait(200);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

这种同步的方式处理,会发现,当这100此循环完成后,页面才会返回 :同步,正在解析......。当后台在循环处理时,前台的页面始终处于等待状态。可以发现,使用都是一个线程在处理:

异步实现方式一

使用线程池,创建新的线程去处理,如下:

    /**
     * 异步处理方式一:线程池,创建新线程处理
	 */
	@GetMapping("/test3")
	public String test3() {
		ExecutorService service = Executors.newFixedThreadPool(5);
		RunnableTask1 task1 = new RunnableTask1();
		service.execute(task1);
		System.out.println("=========》当前线程名:" + Thread.currentThread().getName());

		return "异步,正在解析......";
	}」
public class RunnableTask1 implements Runnable {
	@Override
	public void run() {
		Building building = new Building();

		synchronized (building) {
			try {
				for (int i = 0; i <= 100; i++) {
					System.out.println(Thread.currentThread().getName() + "----------异步:>" + i);
					building.wait(200);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

我们看控制台,会发现,主线程和处理任务的线程,不是一个线程,也就是,当页面请求后,主线程会返回我们想要返回的标识,这里返回的是一个字符串:异步,正在解析......,而线程池新开了一个线程,在后台处理业务逻辑。所以,此时访问接口后,会立马返回,页面不用等待,处理逻辑在后台默默进行。控制台如下:

异步实现方式二

这种方式,是SpringBoot自身的一种异步方式,使用注解实现,非常方便。

SpringBoot要使用@Async需要以下两个步骤:

1.使用@EnableAsync开启异步;(在项目的启动类上)

2.定义Spring组件,使用@Component和@Async;

注意,这里的异步方法,只能在自身之外调用,在本类调用是无效的

        /**
	 * 异步方法
	 * 有@Async注解的方法,默认就是异步执行的,会在默认的线程池中执行,但是此方法不能在本类调用;启动类需添加直接开启异步执行@EnableAsync。
	 */
	@GetMapping("/test1")
	public String test1() {
		taskAsync.getTest1();
		System.out.println(Thread.currentThread().getName() + "=========================");
		return "异步,正在解析......";
	}
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class TaskAsync {

	@Async
	public String getTest1() {
		Building building = new Building();
		synchronized (building) {
			try {
				for (int i = 1; i <= 100; i++) {
					System.out.println(Thread.currentThread().getName() + "----------异步:>" + i);
					building.wait(200);
				}
				return "执行异步任务完毕";
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return Thread.currentThread().getName() + "执行完毕";
	}

}

看控制台,会发现,页面发出请求后,主线程会返回,而内置的线程池会新开线程,在后台执行任务。此时页面不用等待,可以继续其他操作。

可以看到,很多情况下,异步处理,是一种很常见,而且很高效的方式,个人比较喜欢使用springBoot自带的注解方式,只用两个注解即可了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值