A multi-threaded program contains two or more parts that can run concurrently and each part can handle a different task at the same time making optimal use of the available resources.
You can execute requests from multiple threads by writing a multithreaded HttpClient program.
If you want to execute multiple client requests from threads consecutively, you need to create a ClientConnectionPoolManager. It maintains a pool of HttpClientConnections and serves multiple requests from threads.
The connections manager pools the connections based on the route. If the manager has connections for a particular route, then it serves new requests in those routes by leasing an existing connection from the pool, instead of creating a new one.
Follow the steps to execute requests from multiple threads −
Create the Client Connection Pool Manager by instantiating the PoolingHttpClientConnectionManager class.
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
Set the maximum number of connections in the pool using the setMaxTotal() method.
//Set the maximum number of connections in the pool connManager.setMaxTotal(100);
Create a ClientBuilder Object by setting the connection manager using the setConnectionManager() method as shown below −
HttpClientBuilder clientbuilder = HttpClients.custom().setConnectionManager(connManager);
Instantiate the HttpGet class by passing the desired URI to its constructor as a parameter.
HttpGet httpget1 = new HttpGet("URI1"); HttpGet httpget2 = new HttpGet("URI2"); . . . . . . . . . . . .
Make sure that you have created a class, made it a thread (either by extending the thread class or, by implementing the Runnable interface) and implemented the run method.
public class ClientMultiThreaded extends Thread { public void run() { //Run method implementation . . . . . . . . . . } }
Create thread objects by instantiating the Thread class (ClientMultiThreaded) created above.
Pass a HttpClient object, respective HttpGet object and, an integer representing the ID to these threads.
ClientMultiThreaded thread1 = new ClientMultiThreaded(httpclient,httpget1, 1); ClientMultiThreaded thread2 = new ClientMultiThreaded(httpclient,httpget2, 2); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Start all the threads using start() method and join them using the join method().
thread1.start(); thread2.start(); . . . . . . . . thread1.join(); thread2.join(); . . . . . . . . . . . .
Within the run method, execute the request, retrieve the response and print the results.
Following example demonstrates the execution of HTTP requests simultaneously from multiple threads. In this example, we are trying to execute various requests from various threads and trying to print the status, and the number of bytes read by each client.
import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; public class ClientMultiThreaded extends Thread { CloseableHttpClient httpClient; HttpGet httpget; int id; public ClientMultiThreaded(CloseableHttpClient httpClient, HttpGet httpget, int id) { this.httpClient = httpClient; this.httpget = httpget; this.id = id; } @Override public void run() { try{ //Executing the request CloseableHttpResponse httpresponse = httpClient.execute(httpget); //Displaying the status of the request. System.out.println("status of thread "+id+":"+httpresponse.getStatusLine()); //Retrieving the HttpEntity and displaying the no.of bytes read HttpEntity entity = httpresponse.getEntity(); if (entity != null) { System.out.println("Bytes read by thread thread "+id+": "+EntityUtils.toByteArray(entity).length); } }catch(Exception e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws Exception { //Creating the Client Connection Pool Manager by instantiating the PoolingHttpClientConnectionManager class. PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); //Set the maximum number of connections in the pool connManager.setMaxTotal(100); //Create a ClientBuilder Object by setting the connection manager HttpClientBuilder clientbuilder = HttpClients.custom().setConnectionManager(connManager); //Build the CloseableHttpClient object using the build() method. CloseableHttpClient httpclient = clientbuilder.build(); //Creating the HttpGet requests HttpGet httpget1 = new HttpGet("http://www.howcodex.com/"); HttpGet httpget2 = new HttpGet("http://www.google.com/"); HttpGet httpget3 = new HttpGet("https://www.qries.com/"); HttpGet httpget4 = new HttpGet("https://in.yahoo.com/"); //Creating the Thread objects ClientMultiThreaded thread1 = new ClientMultiThreaded(httpclient,httpget1, 1); ClientMultiThreaded thread2 = new ClientMultiThreaded(httpclient,httpget2, 2); ClientMultiThreaded thread3 = new ClientMultiThreaded(httpclient,httpget3, 3); ClientMultiThreaded thread4 = new ClientMultiThreaded(httpclient,httpget4, 4); //Starting all the threads thread1.start(); thread2.start(); thread3.start(); thread4.start(); //Joining all the threads thread1.join(); thread2.join(); thread3.join(); thread4.join(); } }
On executing, the above program generates the following output −
status of thread 1: HTTP/1.1 200 OK Bytes read by thread thread 1: 36907 status of thread 2: HTTP/1.1 200 OK Bytes read by thread thread 2: 13725 status of thread 3: HTTP/1.1 200 OK Bytes read by thread thread 3: 17319 status of thread 4: HTTP/1.1 200 OK Bytes read by thread thread 4: 127018