Is Resttemplate Thread Safe

Is RestTemplate thread safe?

RestTemplate is thread safe (emphasis added):

Conceptually, it is very similar to the JdbcTemplate, JmsTemplate, and the various other templates found in the Spring Framework and other portfolio projects. This means, for instance, that the RestTemplate is thread-safe once constructed


Objects of the RestTemplate class do not change any of their state information to process HTTP: the class is an instance of the Strategy design pattern, rather than being like a connection object. With no state information, there is no possibility of different threads corrupting or racing state information if they share a RestTemplate object. This is why it is possible for threads to share these objects.

If you examine the source code of RestTemplate you will see that it does not use synchronized methods or volatile fields to provide thread-safety after construction of the object. So it is not safe to modify a RestTemplate object after construction. In particular, it is unsafe to add a message converter.

To provide it with a list of message converters you must do one of the following:

  • Use the RestTemplate(List<HttpMessageConverter<?>> messageConverters) constructor. As the internal list of messageConverters is final, this safely publishes the list of message converters.
  • Use the setMessageConverters(List<HttpMessageConverter<?>> messageConverters) mutator and then safely-publish the changed RestTemplate object. Using a Spring bean definition that has a <property name="messageConverters"><list>... does this, as the bean will be safely published by the thread setting up the container in most practical use cases.
  • Use List.add on the reference returned by getMessageConverters() and then safely publish the changed RestTemplate object. However, the documentation for RestTemplate does not explicitly state that it returns a reference that can be used to alter the list of message converters. The current implementation does, but possibly the implementation might be changed to return a Collections.unmodifiableList or a copy of the list. So it might be better not to change it this way.

Note that the first case is the only means of setting up the message converters when constructing the object, so it is correct to say that it "is thread safe once constructed".

The class is part of the Spring Framework, so in almost all practical cases objects of the class will be set up as part of a Spring Application Context, using the first (dependency injection using a constructor) or second (dependency injection using a setter) methods, and so would be guaranteed to be safely published to multiple threads.

How to test thread-safety of RestTemplate?

First of all it is not necessary to call the actual service. You can write your own service and call it simultaneously and stall it or whatever your plan is.

Second - it doesn't make sense to test code outside of your code base. RestTemplate is thread-safe - no need to prove that.

That being said - you can create a bunch of threads, inside of which you invoke the same calls to your single restTemplate instance. You can sleep the threads for some seconds to be "sure" that the restTemplates call will be fired simultaneously.

Go one abstraction level higher and use ExecutorService (e.g. Executors.newFixedThreadPool(N);) and submit callables to it (that call the same restTemplate instance).

Some external to JDK options are JMeter and concurrent-junit.

How to efficiently use RestTemplate in multithreading application?

RestTemplate is thread safe in Spring. So what you may want to do is create only one instance of RestTemplate in your application and share it across multiple threads. This is of course assuming that you will use the same HTTP properties(like timeout,set alive etc) for all. In case you need to change the connection properties you can create a pool at app start of RestTemplate objects and use this to inject the RestTemplate instance to the caller class.

How to use RestTemplate efficiently in Multithreaded environment?

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.

Is it better to keep RestTemplate in memory than creating new RestTemplate with every request?

RestTemplate is designed to be thread-safe and reusable.

RestTemplate is just a facade that doesn't perform actual network operations. It delegates network operations to a HTTP client implementation. This HTTP client implementation can be expensive to create and often handles network level optimizations e.g. caching of connections per origin. You usually want to reuse this HTTP client implementation and this can be achieved by reusing RestTemplate.

Normally you would create RestTemplate as a singleton bean within Spring context. Especially in Spring Boot this is important and you shouldn't use new RestTemplate() syntax because it will not inject all registered customizers.

RestTemplate should be static globally declared?

It doesn't matter either way, static or instance.

RestTemplate's methods for making HTTP requests are thread safe so whether you have a RestTemplate instance per Task instance or a shared instance for all Task instances is irrelevant (except for garbage collection).

Personally, I would create the RestTemplate outside the Task class and pass it as an argument to a Task constructor. (Use Inversion of Control whenever possible.)



Related Topics



Leave a reply



Submit