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.
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;
}
}
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;
}
}
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
}
}
}
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..
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.
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..
May be to use ConnectionFactory in the RestTemplate constructor? Any thoughts?
UPDATE:-
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;
}
}
And below my 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.
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.
As you stated, recreating a new instance of RestTemplate
for each Task
instance is wasteful.
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;
}
}
This way you share the RestTemplate
instance between all your Task
objects.
Note that RestTemplate
uses SimpleClientHttpRequestFactory
to create its connections.