2015-10-15 73 views
0

我需要开发与CXF 3被Tomcat 7.我们的模型层托管的Web服务操作是春季3 此操作调用由远程服务器托管的其他16个网络服务。我们需要等待所有的回应,以构建我们自己的行动的回应。 我们目前依次调用每个遥远的操作。当然,我们有响应时间问题。我认为我们应该平行操作内部调用并同步不同的响应。如何将并行进程同步到Web服务中?

什么样的多线程实现可以是安全的吗?我们可以做些什么来改善它?

回答

1

我会在@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()); 
} 
+0

感谢您的答复。这个解决方案可以在一个tomcat容器内实现而不会遇到非托管线程问题? –

+0

是的,它全部由Spring管理,除非Spring中有任何错误,否则你会没事的。 – Dariusz

+0

感谢您的回复。 –

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 

时间应该是+/-最长检索。 我使代码非常通用(总体上在线程实现中),但它有意适合大多数情况。

享受!

+0

感谢您的回复。 –

+0

使用tomcat时,是否有创建非托管线程的风险?如果您在一些线程仍然存在的情况下尝试阻止Tomcat,我们会遇到问题吗? (对不起,我的英文不好) –

+0

@Yann呃......只要你安全地编码,它就是安全的。使用Spring,您可以使用bean的生命周期回调来确保在关闭Tomcat时所有线程都已完成。检查出来[这里](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-lifecycle) – Thiamath