This question already has answers here:
Best Practice to Use HttpClient in Multithreaded Environment
(5 answers)
Closed 4 years ago.
I've a query regarding HttpClient.
Do you think for a multi-threaded application, is it a good idea to instantiate a new HttpClient object for each and every incoming request?
HttpClients.custom()
.setConnectionManager(new PoolingHttpClientConnectionManager())
.build();
If not, then in that case we will have only one HttpClient object. Now that singleton HttpClient object can be shared by many threads for rest call execution.
Upon successful execution of our rest call, we usually close the httpclient object inside finally block using HttpClients.closequietly()
Don't you think that closing the singleton httpclient object will create problems in a multi-threaded environment.
How should we handle the scenario then?
As far as I know, it's absolutely fine to use a single instance of HttpClient in multiple threads. In order to handle rest call properly, you need close rest call response, for example, org.apache.http.util.EntityUtils#consumeQuietly can be used.
Related
I'm creating a mod that needs to call a GET request to an endpoint.
I don't care about any result, I just want the request to be sent.
Right now I'm using
HttpClient httpClient = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
And it will block. Because the api takes some time to respond that's not good.
I saw that there's a library called async-http-client but I can't add libraries to my project.
I guess I have to create threads in my mod but that doesn't look like the best solution to me as minecraft mods shouldn't make new threads.
Is there any java package that won't care about the response?
Sending network traffic will always block until it's completed - there's no way around that. In this case it should be perfectly fine to create a new thread to do that actual work - the thread will just block (and not waste CPU resources) for most of the time.
Note that async-http-client will just create it's own threads to do it's work, so it won't help get around this restriction.
In Java EE7, the JAX-RS Client API provides a high-level API for accessing any REST resources. According to the documentation, "Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application. "
In order to avoid create client frequently, I am going to cache the client instance and reuse it. Is the client instance thread safe since it can be used by concurrent threads?
Is there any performance issue if I only create a instance of the client and reuse it for all the requests?
I am not sure but I think this is a implementation-specific decision.
I couldn't find in the JAX-RS 2.0 specification nor in the Javadoc anything granting that javax.ws.rs.client.Client is thread-safe. But in the Resteasy (an implementor of JAX-RS) documentation I found:
One default decision made by HttpClient and adopted by Resteasy is the
use of org.apache.http.impl.conn.SingleClientConnManager, which
manages a single socket at any given time and which supports the use
case in which one or more invocations are made serially from a single
thread. For multithreaded applications, SingleClientConnManager may be
replaced by
org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager:
ClientConnectionManager cm = new ThreadSafeClientConnManager();
HttpClient httpClient = new DefaultHttpClient(cm);
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
Source: http://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html/RESTEasy_Client_Framework.html#transport_layer
Based in these information I guess that the answer for your question is likely to be "no".
PLEASE BE AWARE: Although this is the accepted answer, this is implementation specific and was correct for the Jersey 1 Client. For that you absolutely should share a single instance. Creating a client per request is a huge performance overhead
The JavaDoc is mostly answering your question already- yes it's thread-safe and you can and should reuse it. There can be a performance issue from not reusing it, i.e. if you create a Client for every HTTP request you make your performance will suck really bad.
Can anyone help me to clarify how HttpClient behaves in multithreading?
When I create HttpClient object via the code below, should I keep the object globally across the app life cycle (this method is suggested in HttpClient doc), or should I create every time when I want to perform Http connection (Get and Post)?
1)
Static HttpClient httpclient = HttpClientBuilder.create().build(); //so we can use this object in everywhere.
2)
HttpClient httpclient = HttpClientBuilder.create().build(); //do this every time when we want to establish http connect.
What is the best way to make sure the Http connections will not block each other and to make sure they can run concurrently?
Use a PoolingConnectionManager and configure how many connections per route you need (make sure you have as many connections as you have threads using them). Then you can simply inject the same httpclient everywhere. I've been using it like this for several years.
Also consider using ResponseHandlers everywhere; this vastly simplifies releasing of resources and connections.
I am a java beginner, I met a problem in my Restful class, I just wonder when my code is working on the Restful Class, like the thread is still working on one url request, at the same time I send another request to invoke the same Restful Class, this can work properly or not?
Now, I set a client using "GET" method. Do I need to change the method "GET" so the thread does not need to wait to the "Response"?
Any help, thanks a lot~
When you are using a framework, things are very easy. To answer your questions
How does the class behave when two simultaneous requests are made?
Each of your request will run in a separate thread. So its as simple as two different threads accessing a method simultaneously. Care must be taken not to use any shared resources (including instance variables) in the method. In that case, this becomes a bit tricky.
Do I need to change the method "GET" so the thread does not need to wait to the "Response"?
I am not sure what you mean by this. When you use HTTP, a request will always be accompanied by a response. That's how the the protocol works. Even in case of an asynchronous scenario, an immediate notional response is always returned.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to make an make a web request in an async manner
I need to make a non blocking asynchronous method call from my application.
There is an http url which i need to call but in asynchronous way.
example:
URL myPage = new URL("http://www.mypage.com/");
URLConnection yc = myPage.openConnection();
but the method to be invoked in non blocking or asynchronous way, so that the thread doesn't get stuck when the server of the target url ( http://www.mypage.com) is not working.
Using Oracle Weblogic Server 10.3.2
You could do it manually by spawning additional thread, or you could use ready-made library that will to the job for you. Have a look at Apache HttpClient+HttpAsyncClient and these examples