Spring Boot实战|异步调用

《JavaEE开发的颠覆者: Spring Boot实战》系列读书笔记

Spring boot异步调用@Async


什么是异步调用?

  • 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行。

如何实现异步调用?

  • 多线程是一种实现异步调用的方式,在非spring目项目中我们要实现异步调用的就是使用多线程方式,可以自己实现Runable接口或者集成Thread类,或者使用Executors线程池。

    SpringBoot中则提供了很方便的方式执行异步调用,一个@Async就可搞定。

开始使用

  • 在启动类上加上@EnableAsync注解开启异步

controller层

  • 写一个同步接口和异步接口,在需要异步的执行方法上添加@Async注解

    @RequestMapping("async")
    @RestController
    public class AsyncTaskController {
    	
    	@Autowired
    	private AsyncTask asyncTask;
    
    	@RequestMapping(value = "doTask",method = RequestMethod.GET)
    	public String doTask() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		asyncTask.task1();
    		asyncTask.task2();
    		asyncTask.task3();
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("异步任务总耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    		return "success";
    		
    	}
    	@RequestMapping("justDo")
    	public String justDo() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		task1();
    		task2();
    		task3();
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务总耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    		return "success";
    
    	}
    
    	@RequestMapping("doTaskSuccess")
    	public String doTaskSuccess() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Future<String> task1 = asyncTask.task1s();
    		Future<String> task2 = asyncTask.task2s();
    		Future<String> task3 = asyncTask.task3s();
    		String result = null;
    		for (;;) {
    			if(task1.isDone() && task2.isDone() && task3.isDone()) {
    				// 三个任务都调用完成,退出循环等待
    				break;
    			}
    			//Thread.sleep(1000);
    		}
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("异步任务总耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    		return "success";
    	}
    
    	public String threadAsynchSayHello() {
    		Runnable runnable = ()-> {
    			try {
    				long currentTimeMillis = System.currentTimeMillis();
    				Thread.sleep(1000);
    				long currentTimeMillis1 = System.currentTimeMillis();
    				System.out.println("任务三耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		};
    		System.out.println(Thread.currentThread().getName()+"  开启新线程");
    		new Thread(runnable).start();
    		return "success";
    	}
    
    
    	public void task1() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务一耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    
    	public void task2() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务二耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    	public void task3() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务三耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    }
    

异步任务类

  • 将异步任务单独放到一个类中

    @Component
    public class AsyncTask {
    
    	/**
    	 * 异步-无返回值
    	 * @throws InterruptedException
    	 */
    	@Async
    	public void task1() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务一耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    	
    	@Async
    	public void task2() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务二耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    	@Async
    	public void task3() throws InterruptedException{
    		long currentTimeMillis = System.currentTimeMillis();
    		Thread.sleep(1000);
    		long currentTimeMillis1 = System.currentTimeMillis();
    		System.out.println("任务三耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
    	}
    }
    
  • 如何知道异步任务什么时候执行完,执行的结果怎样呢?可以采用添加Fature回调方式判断

    /**
        	 * 异步-  future回调方式
        	 * @return
        	 * @throws InterruptedException
        	 */
        	@Async
        	public Future<String> task1s() throws InterruptedException{
        		long currentTimeMillis = System.currentTimeMillis();
        		Thread.sleep(1000);
        		long currentTimeMillis1 = System.currentTimeMillis();
        		System.out.println("任务一耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
        		return new AsyncResult<String>("任务一执行完毕");
        	}
        
        	@Async
        	public Future<String> task2s() throws InterruptedException{
        		long currentTimeMillis = System.currentTimeMillis();
        		Thread.sleep(2000);
        		long currentTimeMillis1 = System.currentTimeMillis();
        		System.out.println("任务二耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
        		return new AsyncResult<String>("任务二执行完毕");
        	}
        	@Async
        	public Future<String> task3s() throws InterruptedException{
        		long currentTimeMillis = System.currentTimeMillis();
        		Thread.sleep(3000);
        		long currentTimeMillis1 = System.currentTimeMillis();
        		System.out.println("任务三耗时:"+(currentTimeMillis1-currentTimeMillis)+"ms");
        		return new AsyncResult<String>("任务三执行完毕");
        	}
    

用postman进行测试:
执行异步:
执行异步
同步执行:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值