【发布时间】:2017-08-22 17:31:49
【问题描述】:
我正在尝试提高 Spring 应用程序的性能,该应用程序调用大约 8-10 个查询,并且根据它查询的数据量,它需要大约 15 到 120 秒,我提出了 CompletableFuture / Future 方式在 Java 8 中这样做。但是,我一直停留在主线程不等待异步线程完成的地步。以下是我目前实现的代码。
我打算返回并使用“Future”和 ThreadPoolExecutor 实现它,并有一个线程等待 threadPoolExecutor 中生成的可调用线程完成以返回数据。
问题:在java中实现CompletableFuture的任何简单方法,并且主线程等待线程池中的所有线程完成,然后再将数据返回给客户端?
InvokeCallable .java
package net.sampleSpring.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
@Component
public class InvokeCallable {
@Autowired
private ApplicationContext context;
// @Autowired
// @Qualifier("threadPoolExecutor")
// private ThreadPoolTaskExecutor executorThreadPool;
public void invokeCallables() throws InterruptedException, ExecutionException {
List<CompletableFuture<Integer>> lst = new ArrayList<>();
CallableOne callableOne = context.getBean(CallableOne.class);
CallableTwo callableTwo = context.getBean(CallableTwo.class);
CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(new Supplier<Integer>() {
@Override
public Integer get() {
try {
return callableOne.call();
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
}
);
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(new Supplier<String>() {
@Override
public String get() {
try {
return callableTwo.call();
} catch (Exception e) {
e.printStackTrace();
}
return "1";
}
}
);
CompletableFuture.allOf(completableFuture1, completableFuture2).thenApply(
i -> {
System.out.println("Completed running the futures");
System.out.println("future 1" + completableFuture1.join().toString());
System.out.println("future 2" + completableFuture2.join().toLowerCase());
return i;
}
);
}
}
CallableTwo.java
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.concurrent.Callable;
@Component
@Scope("prototype")
public class CallableTwo {
public String call() throws Exception {
Thread.sleep(2000);
return "1000";
}
}
CallableOne.java
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class CallableOne {
public Integer call() throws Exception {
Thread.sleep(2000);
return 1;
}
}
sampleSpringResource.java 使用 Restful 服务调用 InvokeCallable.java 的代码
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.util.concurrent.ExecutionException;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.json.XMLTokener.entity;
/* ItemValue Web service
*
*/
@Path("/")
@Service
public class sampleSpringResource {
@Inject
private InvokeCallable callable;
private static final Logger LOG = LogManager.getLogger();
@GET
@Path("/changeme/")
@Produces(APPLICATION_JSON)
public Response getsampleSpring() throws ExecutionException, InterruptedException {
callable.invokeCallables();
}
}
【问题讨论】:
-
简单的谷歌搜索:spring.io/guides/gs/async-method
-
@AbhijitSarkar 谢谢,会试试看。有些人错过了它。
标签: java spring multithreading java-8 completable-future