我正在开发一个项目,在该项目中,我需要对正在运行Restful Service
的服务器进行HTTP URL调用,该服务器会以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;
}
}
下面是我的
Task
类,该类实现Callable
接口(interface)并使用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
中具有以下代码,该类依次调用getData
类TimeoutThreadExample
中的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设为静态,则在注释掉可衡量性能的
RestTemplate
类中的line1和line2之后,与非静态DemoTest
相比,我看到了更好的端到端性能。通常,在多线程环境中使用
RestTemplate
的正确方法是什么?当前,我依次调用getData
方法5000次,但有些客户会以多线程方式调用它,因此需要了解在多线程环境中使用RestTemplate的最佳方法是什么。可能是在RestTemplate构造函数中使用ConnectionFactory吗?有什么想法吗?
更新:-
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;
}
}
最佳答案
如果我不明白您的问题,请纠正我。似乎与上一个here非常相似。
在那里,我们确定RestTemplate
是线程安全的。因此,没有理由不在有意义的地方共享它。无论您在哪里以相同的方式使用它。
您的示例似乎是执行此操作的理想场所。
如您所述,为每个RestTemplate
实例重新创建一个Task
实例是浪费的。
我会在RestTemplate
中创建TimeoutThreadExample
并将其作为构造函数参数传递给Task
。
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
对象之间共享Task
实例。请注意,
RestTemplate
使用SimpleClientHttpRequestFactory
创建其连接。关于java - 如何在多线程环境中有效使用RestTemplate?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21242812/