如何在multithreading环境中有效地使用RestTemplate?

我正在开发一个项目,我需要对运行Restful Service服务器进行HTTP URL调用,该Restful Service将响应作为JSON字符串返回。

以下是我使用futurecallables主要代码 –

 public class TimeoutThreadExample { private ExecutorService executor = Executors.newFixedThreadPool(10); public String getData() { Future future = executor.submit(new Task()); String response = null; try { response = future.get(100, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return response; } } 

下面是我的Task类,它实现了Callable接口并使用了RestTemplate

 class Task implements Callable { private RestTemplate restTemplate = new RestTemplate(); public String call() throws Exception { String url = "some_url"; String response = restTemplate.getForObject(url, String.class); return response; } } 

现在我在另一个类DemoTest有下面的代码,它在TimeoutThreadExample类中依次调用getData方法5000 times

 public class DemoTest { public static void main(String[] args) { TimeoutThreadExample bc = new TimeoutThreadExample(); for (int i = 0; i <= 5000; i++) { // TimerTest timer = TimerTest.getInstance(); // line 1 bc.getData(); // timer.getDuration(); // line 2 } } } 

所以我的问题是RestTemplate应该在我的Task class是静态的,就好像我正确地看到它一样,我正在为RestTemplate中的每个请求重新创建整个连接池,这不是正确的方法我猜…

注意:如果我将RestTemplate设置为静态,那么在DemoTest类中测量出line1和line2后测量性能时,与非静态RestTemplate相比,我看到端到端的性能更好。

一般来说,在multithreading环境中使用RestTemplate的正确方法是什么? 目前我逐个调用getData方法5000次,但有些客户会以multithreading方式调用它,所以需要知道在multithreading环境中使用RestTemplate的最佳方法是什么。

可能是在RestTemplate构造函数中使用ConnectionFactory? 有什么想法吗?

更新: –

 public class TimeoutThreadExample { private ExecutorService executor = Executors.newFixedThreadPool(10); private RestTemplate restTemplate = new RestTemplate(); public String getData() { Future future = executor.submit(new Task(restTemplate)); String response = null; try { response = future.get(100, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return response; } } 

在我的TaskClass下面 –

 class Task implements Callable { private RestTemplate restTemplate; public Task(RestTemplate restTemplate) { this.restTemplate = restTemplate; } public String call() throws Exception { String url = "some_url"; String response = restTemplate.getForObject(url, String.class); return response; } } 

如果我不明白你的问题,请纠正我。 它似乎与前一个非常相似。

在那里,我们确定RestTemplate是线程安全的。 因此没有理由不在任何有意义的地方分享它,即。 无论你以何种方式使用它。 你的例子似乎是完美的地方。

如上所述,为每个Task实例重新创建RestTemplate的新实例是浪费。

我将在RestTemplate中创建TimeoutThreadExample并将其作为构造函数参数传递给Task

 class Task implements Callable { private RestTemplate restTemplate; public Task(RestTemplate restTemplate) { this.restTemplate = restTemplate; } public String call() throws Exception { String url = "some_url"; String response = restTemplate.getForObject(url, String.class); return response; } } 

这样,您可以在所有Task对象之间共享RestTemplate实例。

请注意, RestTemplate使用SimpleClientHttpRequestFactory来创建其连接。

我在spring有这样的multithreading安全单件REST模板:

                           

请注意我正在使用OAuthRestTemplate ,而myResource指的是我省略的oauth资源,因为它不相关。 您可以轻松使用org.springframework.web.client.RestTemplate而不是OAuthRestTemplate http://docs.spring.io/spring/docs/3.2.4.RELEASE/javadoc-api/org/springframework/web/客户机/ RestTemplate.html

RestTemplate 一旦构造就是线程安全的 ,因此您可以构造一个实例并让所有任务共享它。 这样会更有效率,因为您可以消除每项任务的构建成本,并减少垃圾收集器的负载。