介绍
同步调用
先来演示一下什么是同步调用
@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方法是阻塞方法,没有结果返回时会一直阻塞。