我需要开发与CXF 3被Tomcat 7.我们的模型层托管的Web服务操作是春季3 此操作调用由远程服务器托管的其他16个网络服务。我们需要等待所有的回应,以构建我们自己的行动的回应。 我们目前依次调用每个遥远的操作。当然,我们有响应时间问题。我认为我们应该平行操作内部调用并同步不同的响应。如何将并行进程同步到Web服务中?
什么样的多线程实现可以是安全的吗?我们可以做些什么来改善它?
我需要开发与CXF 3被Tomcat 7.我们的模型层托管的Web服务操作是春季3 此操作调用由远程服务器托管的其他16个网络服务。我们需要等待所有的回应,以构建我们自己的行动的回应。 我们目前依次调用每个遥远的操作。当然,我们有响应时间问题。我认为我们应该平行操作内部调用并同步不同的响应。如何将并行进程同步到Web服务中?
什么样的多线程实现可以是安全的吗?我们可以做些什么来改善它?
我会在@Service
中使用Java的通用Future
s和Spring的@Async
方法。
总之,您按顺序致电服务并获得所有结果为Future
s,然后您只需检查是否所有期货都已完成处理。如果存在这种可能性,您也可以使用部分数据做一些工作。
这里的a simple example关于如何做到这一点。从链接示例服务:
@Service
public class GitHubLookupService {
RestTemplate restTemplate = new RestTemplate();
@Async
public Future<User> findUser(String user) throws InterruptedException {
System.out.println("Looking up " + user);
User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return new AsyncResult<User>(results);
}
}
和一种方法使用它:
@Override
public void run(String... args) throws Exception {
// Start the clock
long start = System.currentTimeMillis();
// Kick of multiple, asynchronous lookups
Future<User> page1 = gitHubLookupService.findUser("PivotalSoftware");
Future<User> page2 = gitHubLookupService.findUser("CloudFoundry");
Future<User> page3 = gitHubLookupService.findUser("Spring-Projects");
// Wait until they are all done
while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
Thread.sleep(10); //10-millisecond pause between each check
}
// Print results, including elapsed time
System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
System.out.println(page1.get());
System.out.println(page2.get());
System.out.println(page3.get());
}
我会用join()
等待使用传统方法的线程来完成,而不是轮询(我不比如轮询模式太多)。本作的一通用线程
类复制:
public class ThreadedWebServiceRetrieval extends Thread {
private List<ResultObject> resultList;
private GenericWebServiceStub stub;
public ThreadedWebServiceRetrieval (List<ResultObject> resultList, GenericWebServiceStub stub) {
this.resultList = resultList;
this.stub = stub;
}
public void run() {
resultList.add(stub.retrieveData());
}
}
这对于并行检索代码:
这种方法的// ... Controller/Service stuff
List<ResultObject> resultList = new LinkedList<>();//Diamond operator
List<Thread> webServiceList = new LinkedList<>();
webServiceList.add(new ThreadedWebServiceRetrieval(resultList, stub1));
//...
webServiceList.add(new ThreadedWebServiceRetrieval(resultList, stubN));
for (Thread thread : webServiceList) {
thread.start();
}
for (Thread thread : webServiceList) {
thread.join();
}
// resultList is fulfilled
时间应该是+/-最长检索。 我使代码非常通用(总体上在线程实现中),但它有意适合大多数情况。
享受!
感谢您的回复。 –
使用tomcat时,是否有创建非托管线程的风险?如果您在一些线程仍然存在的情况下尝试阻止Tomcat,我们会遇到问题吗? (对不起,我的英文不好) –
@Yann呃......只要你安全地编码,它就是安全的。使用Spring,您可以使用bean的生命周期回调来确保在关闭Tomcat时所有线程都已完成。检查出来[这里](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-lifecycle) – Thiamath
感谢您的答复。这个解决方案可以在一个tomcat容器内实现而不会遇到非托管线程问题? –
是的,它全部由Spring管理,除非Spring中有任何错误,否则你会没事的。 – Dariusz
感谢您的回复。 –