0
点赞
收藏
分享

微信扫一扫

Spring@Async注解实现方法的异步调用


介绍

同步调用

先来演示一下什么是同步调用

@Component
public class Task {

public void doTaskOne() throws InterruptedException {
System.out.println("doTaskOne start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskOne end " + System.currentTimeMillis());
}

public void doTaskTwo() throws InterruptedException {
System.out.println("doTaskTwo start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskTwo end " + System.currentTimeMillis()) ;
}
}

测试方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskTest {

@Autowired
Task task;

@Test
public void doTask() throws InterruptedException {
task.doTaskOne();
task.doTaskTwo();
}
}

输出如下

doTaskOne start 1566121320372
doTaskOne end 1566121321373
doTaskTwo start 1566121321373
doTaskTwo end 1566121322374

可以看到方法一执行完毕,方法二才会执行

异步调用不返回值

1.Spring Boot启动类上加@EnableAsync注解

@SpringBootApplication
@EnableAsync

2.方法上加@Async注解

@Component
public class Task {

@Async
public void doTaskOne() throws InterruptedException {
System.out.println("doTaskOne start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskOne end " + System.currentTimeMillis());
}

@Async
public void doTaskTwo() throws InterruptedException {
System.out.println("doTaskTwo start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskTwo end " + System.currentTimeMillis()) ;
}
}

测试类如下

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskTest {

@Autowired
Task task;

@Test
public void doTask() throws InterruptedException {
task.doTaskOne();
task.doTaskTwo();
TimeUnit.SECONDS.sleep(3);
}
}

最后的TimeUnit.SECONDS.sleep(3)保证主线程存活,不然主线程执行完看不到子线程输出的end,输出如下

doTaskOne start 1566121729140
doTaskTwo start 1566121729140
doTaskOne end 1566121730140
doTaskTwo end 1566121730140

看输出,2个任务同时启动。2个没有关系的任务以前需要2s才能执行完,异步后1s就能执行完,效率提高。

异步调用返回值

@Component
public class Task {

@Async
public Future<String> doTaskOne() throws InterruptedException {
System.out.println("doTaskOne start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskOne end " + System.currentTimeMillis());
return new AsyncResult<>("taskOne return");
}

@Async
public Future<String> doTaskTwo() throws InterruptedException {
System.out.println("doTaskTwo start " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(1);
System.out.println("doTaskTwo end " + System.currentTimeMillis());
return new AsyncResult<>("taskTwo return");
}
}

测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskTest {

@Autowired
Task task;

@Test
public void doTask() throws InterruptedException, ExecutionException {
Future<String> future1 = task.doTaskOne();
Future<String> future2 = task.doTaskTwo();
String result1 = future1.get();
System.out.println(result1);
String result2 = future2.get();
System.out.println(result2);
}
}

输出如下

doTaskTwo start 1566122170684
doTaskOne start 1566122170684
doTaskTwo end 1566122171684
doTaskOne end 1566122171684
taskOne return
taskTwo return

Future类的get方法是阻塞方法,没有结果返回时会一直阻塞。



举报

相关推荐

0 条评论