Java 如何在多线程环境中有效地使用RestTemplate?
我正在做一个项目,在这个项目中,我需要对运行Java 如何在多线程环境中有效地使用RestTemplate?,java,multithreading,static,connection-pooling,resttemplate,Java,Multithreading,Static,Connection Pooling,Resttemplate,我正在做一个项目,在这个项目中,我需要对运行Restful服务的服务器进行一个httpurl调用,该服务以JSON字符串的形式返回响应 下面是我的主要代码,它使用的是future和callables- public class TimeoutThreadExample { private ExecutorService executor = Executors.newFixedThreadPool(10); public String getData() {
Restful服务的服务器进行一个httpurl调用,该服务以JSON字符串的形式返回响应
下面是我的主要代码,它使用的是future
和callables
-
public class TimeoutThreadExample {
private ExecutorService executor = Executors.newFixedThreadPool(10);
public String getData() {
Future<String> 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;
}
}
现在我在另一个类demost
中有下面的代码,它依次调用TimeoutThreadExample
类5000次中的getData
方法-
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
}
}
}
在我的任务类下
class Task implements Callable<String> {
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 RestTemplate;
公共任务(RestTemplate RestTemplate){
this.restTemplate=restTemplate;
}
公共字符串调用()引发异常{
String url=“some_url”;
String response=restTemplate.getForObject(url,String.class);
返回响应;
}
}
如果我不明白你的问题,请纠正我。它似乎与前一个非常相似
在这里,我们确定restemplate
是线程安全的。因此,没有理由不在任何有意义的地方分享它,例如,无论你以同样的方式使用它的地方。
你的例子似乎是这样做的最佳场所
如前所述,为每个任务
实例重新创建restemplate
的新实例是浪费
我将在TimeoutThreadExample
中创建restemplate
,并将其作为构造函数参数传递给任务
class Task implements Callable<String> {
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 RestTemplate;
公共任务(RestTemplate RestTemplate){
this.restTemplate=restTemplate;
}
公共字符串调用()引发异常{
String url=“some_url”;
String response=restTemplate.getForObject(url,String.class);
返回响应;
}
}
通过这种方式,您可以在所有任务
对象之间共享restemplate
实例
请注意,RestTemplate
使用SimpleClientHttpRequestFactory
创建其连接。我的多线程安全单例REST模板在spring中是这样连接的:
<bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams" id="httpConnectionManagerParams">
<property name="connectionTimeout" value="10000"/>
</bean>
<bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager" id="httpConnectionManager">
<property name="params" ref="httpConnectionManagerParams"/>
</bean>
<bean class="org.apache.commons.httpclient.params.HttpClientParams" id="httpClientParams">
<property name="authenticationPreemptive" value="true"/>
<property name="soTimeout" value="10000"/>
</bean>
<bean class="org.apache.commons.httpclient.HttpClient" id="httpClient">
<constructor-arg ref="httpClientParams"/>
<constructor-arg ref="httpConnectionManager"/>
</bean>
<bean class="org.springframework.http.client.CommonsClientHttpRequestFactory" id="httpClientFactory">
<constructor-arg ref="httpClient"/>
</bean>
<bean class="org.springframework.security.oauth.consumer.client.OAuthRestTemplate" id="restTemplate">
<constructor-arg ref="httpClientFactory"/>
<constructor-arg ref="myResource"/>
<property name="messageConverters">
<list>
<ref bean="marshallingHttpMessageConverter"/>
</list>
</property>
</bean>
请注意,我使用的是一个OAuthRestTemplate
,而myResource
指的是我忽略的oauth资源内容,因为它不相关。您可以轻松地使用org.springframework.web.client.restemplate
arestemplate
,而不是OAuthRestTemplate
,这样您就可以构建一个实例并让所有任务共享它。这将更有效率,因为您消除了每个任务的构建成本,并减少了垃圾收集器的负载 我明白了。。简言之,它们都是一样的。。在任务类中制作静态文件?或者通过传递对象来使用DI?RestTemplate是线程安全的,但您还必须确保下面的http连接管理器是线程安全的,例如使用org.apache.commons.httpclient.multi-threadedHttpConnectionManager
(请注意,我使用的是commons httpclient 3.1,因此这可能不适用于其他版本)另一个接近的副本:。显然OP在这里有两个身份,从这个意义上说,是的。顺便说一句,我真诚地建议您研究一下URLConnection的实现——我认为您会改变“更难使用”的想法:)可能的重复
class Task implements Callable<String> {
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;
}
}
<bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams" id="httpConnectionManagerParams">
<property name="connectionTimeout" value="10000"/>
</bean>
<bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager" id="httpConnectionManager">
<property name="params" ref="httpConnectionManagerParams"/>
</bean>
<bean class="org.apache.commons.httpclient.params.HttpClientParams" id="httpClientParams">
<property name="authenticationPreemptive" value="true"/>
<property name="soTimeout" value="10000"/>
</bean>
<bean class="org.apache.commons.httpclient.HttpClient" id="httpClient">
<constructor-arg ref="httpClientParams"/>
<constructor-arg ref="httpConnectionManager"/>
</bean>
<bean class="org.springframework.http.client.CommonsClientHttpRequestFactory" id="httpClientFactory">
<constructor-arg ref="httpClient"/>
</bean>
<bean class="org.springframework.security.oauth.consumer.client.OAuthRestTemplate" id="restTemplate">
<constructor-arg ref="httpClientFactory"/>
<constructor-arg ref="myResource"/>
<property name="messageConverters">
<list>
<ref bean="marshallingHttpMessageConverter"/>
</list>
</property>
</bean>