如何在multithreading环境中有效地使用RestTemplate?
我正在开发一个项目,我需要对运行Restful Service
服务器进行HTTP URL调用,该Restful Service
将响应作为JSON字符串返回。
以下是我使用future
和callables
主要代码 –
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
一旦构造就是线程安全的 ,因此您可以构造一个实例并让所有任务共享它。 这样会更有效率,因为您可以消除每项任务的构建成本,并减少垃圾收集器的负载。