我需要使用Tomcat 7托管的CXF 3开发Web服务操作。我们的模型层是Spring 3。 此操作调用远程服务器托管的16个其他Web服务。我们需要等待所有响应,以构建我们自己的操作的响应。 我们目前按顺序调用每个远程操作。当然,我们有响应时间问题。我认为我们应该并行操作内部调用并同步不同的响应。
什么样的多线程实现可以安全?我们可以做些什么来改善它?
答案 0 :(得分:1)
我在Future
中使用Java的通用@Async
和Spring的@Service
方法。
简而言之,您按顺序调用服务并将所有结果作为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());
}
答案 1 :(得分:0)
我会使用传统方法使用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
这种方法的时间应该是+/-最长的检索。 我使代码非常通用(整体在Thread实现中),但它适合大多数情况。
享受!