问题描述
我正在开发一个项目,在该项目中我需要对运行 Restful Service
的服务器进行 HTTP URL 调用,该服务器将响应作为 JSON 字符串返回.
I am working on a project in which I need to make a HTTP URL call to my server which is running Restful Service
which returns back the response as a JSON String.
下面是我的主要代码,它使用了 future
和 callables
-
Below is my main code which is using the future
and 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;
}
}
下面是我的 Task
类,它实现了 Callable
接口并使用了 RestTemplate
...
Below is my Task
class which implements the Callable
interface and uses the RestTemplate
...
class Task implements Callable<String> {
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 次
按顺序 -
And now I have below code in another class DemoTest
which calls the getData
method in TimeoutThreadExample
class 5000 times
sequentially -
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
我猜这不是正确的方法..
So my question is should RestTemplate
be static here in my Task class
as if I see it correctly, I am recreating the whole connection pool for each request in RestTemplate
which is not the right way I guess..
注意:如果我将 RestTemplate 设为静态,那么在注释掉 中的 line1 和 line2 后,与非静态
类,用于衡量性能.RestTemplate
相比,我看到端到端的性能更好DemoTest
NOTE: If I am making RestTemplate static, then I see better performance end to end as compared to non static RestTemplate
after commenting out line1 and line2 in DemoTest
class which measures the performance.
一般来说,在多线程环境中使用 RestTemplate
的正确方法是什么?目前,我正在依次调用 getData
方法 5000 次,但有些客户会以多线程方式调用它,因此需要知道在多线程环境中使用 RestTemplate 的最佳方法是什么..
In general what is the right way to use RestTemplate
in Multithreading environment? Currently I am calling sequentially getData
method 5000 times one by one but some customer will call it in a multithreaded way so need to know what is the best way to have RestTemplate in a multithreaded environment..
可能是在 RestTemplate 构造函数中使用 ConnectionFactory 吗?有什么想法吗?
May be to use ConnectionFactory in the RestTemplate constructor? Any thoughts?
更新:-
public class TimeoutThreadExample {
private ExecutorService executor = Executors.newFixedThreadPool(10);
private RestTemplate restTemplate = new RestTemplate();
public String getData() {
Future<String> 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<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;
}
}
推荐答案
如果我不明白你的问题,请纠正我.它看起来与此处的前一个非常相似.
Correct me if I didn't understand your question. It seems very similar to the previous one here.
在那里,我们确定 RestTemplate
是线程安全的.因此,没有理由不在任何有意义的地方共享它,即.无论您在哪里都以相同的方式使用它.您的示例似乎是这样做的理想场所.
There, we determined that RestTemplate
is thread-safe. There is therefore no reason not to share it wherever it makes sense to, ie. wherever you are using it in the same way.Your example seems like the perfect place to do so.
正如您所说,为每个 Task
实例重新创建一个 RestTemplate
的新实例是一种浪费.
As you stated, recreating a new instance of RestTemplate
for each Task
instance is wasteful.
我将在 TimeoutThreadExample
中创建 RestTemplate
并将其作为构造函数参数传递给 Task
.
I would create the RestTemplate
in TimeoutThreadExample
and pass it to the Task
as a constructor argument.
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;
}
}
通过这种方式,您可以在所有 Task
对象之间共享 RestTemplate
实例.
This way you share the RestTemplate
instance between all your Task
objects.
请注意,RestTemplate
使用 SimpleClientHttpRequestFactory
来创建其连接.
Note that RestTemplate
uses SimpleClientHttpRequestFactory
to create its connections.
这篇关于如何在多线程环境中高效使用 RestTemplate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!