前言
现在大部分的CPU都是多核,我们都知道想要提升我们应用程序的运行效率,就必须得充分利用多核CPU的计算能力;Java早已经为我们提供了多线程的API,但是实现方式略微麻烦,今天我们就来看看Java8在这方面提供的改善。
假设场景
现在你需要为在线教育平台提供一个查询用户详情的API,该接口需要返回用户的基本信息,标签信息,这两个信息存放在不同位置,需要远程调用来获取这两个信息;为了模拟远程调用,我们需要在代码里面延迟 1s;
public interface RemoteLoader {
String load();
default void delay() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CustomerInfoService implements RemoteLoader {
public String load() {
this.delay();
return "基本信息";
}
}
public class LearnRecordService implements RemoteLoader {
public String load() {
this.delay();
return "学习信息";
}
}
同步方式实现版本
如果我们采用同步的方式来完成这个API接口,我们的实现代码:
@Test
public void testSync() {
long start = System.currentTimeMillis();
List<RemoteLoader> remoteLoaders = Arrays.asList(new CustomerInfoService(), new LearnRecordService());
List<String> customerDetail = remoteLoaders.stream().map(RemoteLoader::load).collect(toList());
System.out.println(customerDetail);
long end = System.currentTimeMillis();
System.out.println("总共花费时间:" + (end - start));
}
不出所料,因为调用的两个接口都是延迟了 1s ,所以结果大于2秒
Future实现的版本
接下来我们把这个例子用Java7提供的Future
来实现异步的版本,看下效果如何呢?代码如下:
@Test
public void testFuture() {
long start = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(2);
List<RemoteLoader> remoteLoaders = Arrays.asList(new CustomerInfoService(), new LearnRecordService());
List<Future<String>> futures = remoteLoaders.stream()
.map(remoteLoader -> executorService.submit(remoteLoader::load))
.collect(toList());
List<String> customerDetail = futures.stream()
.map(future -> {
try {
return future.get();
} catch (InterruptedException