假如我有一个订单相关的统计接口,需要返回3样数据:今日订单数、今日交易额、总交易额。
一般的我们的做法是串行调用3个函数,把调用返回的结果返回给调用者,这3次调用时串行执行的,如果每个调用耗时1秒的话,3次调用总耗时就是3秒。
这种做法效率非常低,因为3次调用之间无所谓先后顺序,所以采用并行执行效率会更好。比如使用线程池ExecutorService实现异步调用。
其实Java8提供了一个非常牛逼的CompletableFuture类,也可以实现异步化:
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class OrderService {
/**
* 今日订单数
*
* @return
*/
public CompletableFuture<String> todayOrderCount() {
return CompletableFuture.supplyAsync(() -> this.getTodayOrderCount());
}
public CompletableFuture<String> todayTurnover() {
return CompletableFuture.supplyAsync(() -> this.getTodayTurnover());
}
public CompletableFuture<String> totalTurnover() {
return CompletableFuture.supplyAsync(() -> this.getTotalTurnover());
}
private String getTodayOrderCount() {
System.out.println(">>>>>>> 查询今日订单数:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "50";
}
/**
* 今日交易额
*
* @return
*/
private String getTodayTurnover() {
System.out.println(">>>>>>> 查询今日交易额:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "200";
}
/**
* 总交易额
*
* @return
*/
private String getTotalTurnover() {
System.out.println(">>>>>>> 查询总交易额:" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "800";
}
}
import com.alibaba.fastjson.JSONObject;
import com.example.sb.service.test.impl.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/report")
public JSONObject report() {
long start = System.currentTimeMillis();
JSONObject json = orderReport();
System.out.println("耗时:" + (System.currentTimeMillis() - start));
return json;
}
private JSONObject orderReport() {
CompletableFuture<String> todayOrderCountFuture = orderService.todayOrderCount();
CompletableFuture<String> todayTurnoverFuture = orderService.todayTurnover();
CompletableFuture<String> totalTurnoverFuture = orderService.totalTurnover();
JSONObject json = new JSONObject();
todayOrderCountFuture.whenComplete((v, t) -> {
json.put("todayOrderCountFuture", v);
});
todayTurnoverFuture.whenComplete((v, t) -> {
json.put("todayTurnoverFuture", v);
});
totalTurnoverFuture.whenComplete((v, t) -> {
json.put("totalTurnoverFuture", v);
});
CompletableFuture.allOf(todayOrderCountFuture, todayTurnoverFuture, totalTurnoverFuture)
.thenRun(() -> System.out.println("完成!!!!"))
.join();
return json;
}
}
浏览器访问:http://localhost:8080/order/report 执行结果截图如下:
因为每个OrderService的调用模拟都是耗时1秒,3个调用并行执行,最终耗时自然也是1秒。
作者:不知名的蛋挞
链接:https://www.jianshu.com/p/aa7cc1a73c72
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。