通常,您需要将工作单元封装在
Runnable或中
java.util.concurrent.Callable,然后通过
java.util.concurrent.Executor(或
org.springframework.core.task.TaskExecutor)执行。这允许每个工作单元分别执行,通常以异步方式执行(取决于的实现
Executor)。
因此,对于您的特定问题,您可以执行以下 *** 作:
import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.Executor;import java.util.concurrent.FutureTask;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.BasicResponseHandler;import org.apache.http.impl.client.DefaultHttpClient;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class MyController { //inject this private Executor executor; @RequestMapping("/your/path/here") public String myMVCControllerGETdataMethod(Model model) { //define all async requests and give them to injected Executor List<GetRequestTask> tasks = new ArrayList<GetRequestTask>(); tasks.add(new GetRequestTask("http://api/data?type=1", this.executor)); tasks.add(new GetRequestTask("http://api/data?type=2", this.executor)); //... //do other work here //... //now wait for all async tasks to complete while(!tasks.isEmpty()) { for(Iterator<GetRequestTask> it = tasks.iterator(); it.hasNext();) { GetRequestTask task = it.next(); if(task.isDone()) { String request = task.getRequest(); String response = task.getResponse(); //PUT YOUR CODE HERE //possibly aggregate request and response in Map<String,String> //or do something else with request and response it.remove(); } } //avoid tight loop in "main" thread if(!tasks.isEmpty()) Thread.sleep(100); } //now you have all responses for all async requests //the following from your original pre //note: you should probably pass the responses from above //to this next method (to keep your controller stateless) String results = doWorkwithMultipleDataReturned(); model.addAttribute(results, results); return "index"; } //abstraction to wrap Callable and Future class GetRequestTask { private GetRequestWork work; private FutureTask<String> task; public GetRequestTask(String url, Executor executor) { this.work = new GetRequestWork(url); this.task = new FutureTask<String>(work); executor.execute(this.task); } public String getRequest() { return this.work.getUrl(); } public boolean isDone() { return this.task.isDone(); } public String getResponse() { try { return this.task.get(); } catch(Exception e) { throw new RuntimeException(e); } } } //Callable representing actual HTTP GET request class GetRequestWork implements Callable<String> { private final String url; public GetRequestWork(String url) { this.url = url; } public String getUrl() { return this.url; } public String call() throws Exception { return new DefaultHttpClient().execute(new HttpGet(getUrl()), new BasicResponseHandler()); } }}
请注意,此代码尚未经过测试。
对于您的
Executor实现,请查看Spring的TaskExecutor和task:executor名称空间。您可能需要针对此用例的可重用线程池(而不是每次都创建一个新线程)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)