github项目地址:github.com/lgsdaredevi…html
在应用主类中添加@EnableAsync注解 java
@Async
public Future<String> ansync(String name){
try {
Thread.sleep(10000);
logger.info("这里是异步方法");
logger.info("传过来的名字是:" + name);
name = "修改的名字";
logger.info("修改后的名字是:" + name);
return new AsyncResult<>("name: " + name);
}catch (Exception e){
return new AsyncResult<>("异常");
}
}
复制代码
public String requestAnsync(String name){
try {
Long start = System.currentTimeMillis();
Future<String> result = ansync(name);
if (result.isDone()){
name = result.get();
logger.info("异步方法结束,名字改成:" + name);
}
Long end = System.currentTimeMillis();
logger.info("耗时:" + (int)(end-start));
return "hello " + name;
}catch (Exception e){
logger.error("异常");
return "异常";
}
}
复制代码
若想获取到返回值,应该轮询方法获取,不然若果没有isDone则不会走下面的方法,或者能够使用CompletableFuture:git
2018-07-17 11:31:55.390 INFO 5232 --- [nio-8080-exec-6] c.e.async.service.AsyncTestService : 耗时:0
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 这里是异步方法
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 传过来的名字是:ling
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 修改后的名字是:修改的名字
复制代码
若是使用future.get()方法会阻塞线程直到拿到结果。github
@Async
public void noReturnAsync(String name){
try {
Thread.sleep(10000);
logger.info("这里是异步方法");
logger.info("传过来的名字是:" + name);
name = "修改的名字";
logger.info("修改后的名字是:" + name);
}catch (Exception e){
}
}
复制代码
调用异步的方法spring
public String noReturn(String name){
Long start = System.currentTimeMillis();
asyncTest.noReturnAsync(name);
Long end = System.currentTimeMillis();
logger.info("耗时:" + (int)(end-start));
return "hello " + name;
}
复制代码
若是异步方法变成阻塞的同步方法,可能缘由是异步方法和普通的调用方法在同一个类中,解决方法是将异步方法单独放到一个类中。 产生缘由:spring对@Transactional注解时也有相似问题,spring扫描时具备@Transactional注解方法的类时,是生成一个代理类,由代理类去开启关闭事务,而在同一个类中,方法调用是在类体内执行的,spring没法截获这个方法调用。 具体参见:Spring Boot使用@Async实现异步调用bash