使用场景:
使用异步执行的优点:
异步比同步快很多,节省更多的时间,提高效率
步骤
1,使用注解@EnableAsync开启异步,会自动扫描
@SpringBootApplication
@EnableAsync
public class SchedulingApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulingApplication.class, args);
}
}
2,定义@Component @Async 作为组件被容器扫描执行
返回的Future
@Component
public class AsyncTask {
@Async
public Future doTask1() throws Exception{
long start = System.currentTimeMillis();
Thread.sleep(1000);
long end = System.currentTimeMillis();
System.out.println("任务一耗时:"+ (end-start)+"毫秒");
return new AsyncResult<>(true);
}
@Async
public Future doTask2() throws Exception{
long start = System.currentTimeMillis();
Thread.sleep(700);
long end = System.currentTimeMillis();
System.out.println("任务二耗时:"+ (end-start)+"毫秒");
return new AsyncResult<>(true);
}
@Async
public Future doTask3() throws Exception{
long start = System.currentTimeMillis();
Thread.sleep(600);
long end = System.currentTimeMillis();
System.out.println("任务三耗时:"+ (end-start)+"毫秒");
return new AsyncResult<>(true);
}
}
Controller层执行,
@RestController
@RequestMapping("tasks")
public class DoTask {
@Autowired
private AsyncTask asyncTask;
@RequestMapping("test")
public String test() throws Exception {
long start = System.currentTimeMillis();
Future a = asyncTask.doTask1(); //异步执行
Future b = asyncTask.doTask2(); //异步执行
Future c = asyncTask.doTask3(); //异步执行
while(!a.isDone()||!b.isDone()||!c.isDone()){
if(a.isDone()&&b.isDone()&&c.isDone()){
break;
}
}
long end = System.currentTimeMillis();
String times = "任务全部完成,总耗时:"+(end-start)+"毫秒";
System.out.println(times);
return times;
}
}
Future接口简单介绍
接口函数及含义 :public interface Future
boolean cancel(boolean mayInterruptIfRunning)
取消当前执行的任务,如果已经执行完毕或者已经被取消/由于某种原因不能被取消 则取消任务失败。
参数mayInterruptIfRunning: 当任务正在执行,如果参数为true ,则尝试中断任务,否则让任务继续执行知道结束。
boolean isCancelled()
Returns {@code true} if this task was cancelled before it completed * normally.
boolean isDone();
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
V get() throws InterruptedException, ExecutionException;
/** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return the computed result * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an * exception * @throws InterruptedException if the current thread was interrupted * while waiting */
由注释可以看出,当没有执行完成时,需要等待任务执行完成了才会将计算结果返回。
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
如果等待的时间超过设置的时间则会报 TimeoutException异常。
参考来源:
http://www.cnblogs.com/NeilZhang/p/8870062.html
https://www.imooc.com/video/16793