异步就是意味着并发执行,而不是顺序执行。如图:我给的例子(顺序执行)
@Service
public class AsyncTestImpl implements AsyncTest {
public void executeTask(){
long begin = System.currentTimeMillis();
this.task1();
this.task2();
this.task3();
long end = System.currentTimeMillis();
long time = (end-begin)/1000;
System.out.println(time);
}
public void task1(){
try {
Thread.sleep(1000);
System.out.println("任务1执行===========》 睡眠 1s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void task2(){
try {
Thread.sleep(2000);
System.out.println("任务2执行===========》 睡眠 2s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void task3(){
try {
Thread.sleep(3000);
System.out.println("任务3执行===========》 睡眠 3s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行了6s,但是这个方法是不是3s就可以执行完呢。我把task都改成异步形式
Controller
@RestController
@RequestMapping("/async")
public class AsyncTestController {
@Autowired
private AsyncTestImpl asyncTest;
@GetMapping("/test")
public Map<String,Object> test(){
Map<String,Object> map = new HashMap<String,Object>();
//asyncTest.executeTask();
long begin = System.currentTimeMillis();
asyncTest.task1();
asyncTest.task2();
asyncTest.task3();
long end = System.currentTimeMillis();
long time = (end-begin)/1000;
System.out.println(time);
map.put("status",0);
map.put("msg","ok");
return map;
}
}
@Service
public class AsyncTestImpl implements AsyncTest {
/* @Async
public void executeTask(){
long begin = System.currentTimeMillis();
this.task1();
this.task2();
this.task3();
long end = System.currentTimeMillis();
long time = (end-begin)/1000;
System.out.println(time);
}*/
@Async
public void task1(){
try {
Thread.sleep(1000);
System.out.println("任务1执行===========》 睡眠 1s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async
public void task2(){
try {
Thread.sleep(2000);
System.out.println("任务2执行===========》 睡眠 2s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async
public void task3(){
try {
Thread.sleep(3000);
System.out.println("任务3执行===========》 睡眠 3s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
启动类加上 @EnableAsync
这里有个坑,就是我把异步在同一个类中调用时,不生效。如我代码中的executeTask方法,我调用还是顺序执行。没着了,只能在controller层去调用,原因是因为Spring在启动扫描时会为其创建一个代理类,而同类调用时,还是调用本身的代理类的,所以和平常调用是一样的。
有时,我们还是需要知道任务是否执行完毕,在做一些其他操作,这里要用到任务返回结果Future
@Service
public class AsyncTestImpl implements AsyncTest {
/* @Async
public void executeTask(){
long begin = System.currentTimeMillis();
this.task1();
this.task2();
this.task3();
long end = System.currentTimeMillis();
long time = (end-begin)/1000;
System.out.println(time);
}*/
@Async
public Future<String> task1(){
try {
Thread.sleep(1000);
System.out.println("任务1执行===========》 睡眠 1s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<String>("task1");
}
@Async
public Future<String> task2(){
try {
Thread.sleep(2000);
System.out.println("任务2执行===========》 睡眠 2s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<String>("task2");
}
@Async
public Future<String> task3(){
try {
Thread.sleep(3000);
System.out.println("任务3执行===========》 睡眠 3s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<String>("task3");
}
}
@RestController
@RequestMapping("/async")
public class AsyncTestController {
@Autowired
private AsyncTestImpl asyncTest;
@GetMapping("/test")
public Map<String,Object> test(){
Map<String,Object> map = new HashMap<String,Object>();
//asyncTest.executeTask();
long begin = System.currentTimeMillis();
Future<String> task1 = asyncTest.task1();
Future<String> task2 = asyncTest.task2();
Future<String> task3 = asyncTest.task3();
try {
while(true){
if(task1.isDone() && task2.isDone() && task3.isDone()){
System.out.println(task1.get());
System.out.println(task2.get());
System.out.println(task3.get());
break;
}
}
} catch (Exception e) {
e.toString();
}
long end = System.currentTimeMillis();
long time = (end-begin)/1000;
System.out.println(time);
map.put("status",0);
map.put("msg","ok");
return map;
}
}