SpringBoot 异步任务 EnableAsync

1. 应用场景

  • 处理log
  • 发送邮件、短信

2. 使用步骤

  • 在启动类加注解@EnableAsync开启支持
  • 定义异步任务类,添加@Component注解
  • 异步类中的异步方法加@Async。注意@Async加在类上表示类中所有方法都是异步方法

如:

@SpringBootApplication
@EnableAsync
public class DempProjectApplication {

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

}

@Component
public class CustomAsyncTask {
    
    @Async
    public void task1() throws InterruptedException {
        System.out.println("task1");
        Thread.sleep(2000L);
    }
    @Async
    public void task2() throws InterruptedException {
        System.out.println("task2");
        Thread.sleep(2000L);

    }
}


@RestController
@RequestMapping("/api/v1/pub/demo")
public class DemoController {

    @Autowired
    private CustomAsyncTask task;

    @GetMapping("/task")
    public JsonData testTask(){
        long start = System.currentTimeMillis();
        System.out.println("testTask begin ");

        task.task1();

        task.task2();

        long end = System.currentTimeMillis();
        System.out.println("testTask end"); // 如果不是异步任务,这里应当花费至少4000ms
        return JsonData.buildSuccess("spend " + (end - start));
    }
}

测试

@SpringBootTest
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class MockMvcTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testTask() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
                .get("/api/v1/pub/demo/task"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        MockHttpServletResponse resp = mvcResult.getResponse();
        String rst = resp.getContentAsString(Charset.forName("utf-8"));
        System.out.println(rst);//{"code":0,"msg":null,"data":"spend 6"}
    }


}

3. 异步任务使用Future获取结果

注意点:

  • 要把异步任务封装到类里面,不能直接写到Controller
  • 增加Future 返回结果 AsyncResult(“task执行完成”);
  • 如果需要拿到结果 需要判断全部的 task.isDone()

如:

@Component
public class CustomAsyncTask {

    @GetMapping("/future")
    public JsonData testTaskFuture() {
        long start = System.currentTimeMillis();
        Future<String> task3 = task.task3();
        Future<String> task4 = task.task4();

        while (true){
            if(task3.isDone() && task4.isDone()){
                try {
                    System.out.println(task3.get());
                    System.out.println(task4.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }finally {
                    break;
                }
            }
        }
        long end = System.currentTimeMillis();
        //正常情况下,这里花费的时间应该至少是4000ms,
        //但是task3和task4是异步执行的,虽然get()时会阻塞,但这里最多花费一个任务(以耗时最长的那个为准)的时间
        return JsonData.buildSuccess("spend " + (end - start));
    }


}

测试:

@SpringBootTest
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class MockMvcTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testFuture() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
                .get("/api/v1/pub/demo/future"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

        MockHttpServletResponse resp = mvcResult.getResponse();
        String rst = resp.getContentAsString(Charset.forName("utf-8"));
        System.out.println(rst);//{"code":0,"msg":null,"data":"spend 2018"}
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值