Apache HttpClient - 多线程

多线程程序包含两个或多个可以同时运行的部分,每个部分可以同时处理不同的任务,从而优化利用可用资源。

您可以通过编写多线程 HttpClient 程序来执行来自多个线程的请求。

如果你想从线程中连续执行多个客户端请求,你需要创建一个ClientConnectionPoolManager。 它维护一个 HttpClientConnections 池并为来自线程的多个请求提供服务。

连接管理器根据路由汇集连接。 如果管理器具有特定路由的连接,则它通过从池中租用现有连接而不是创建新连接来为这些路由中的新请求提供服务。

按照步骤执行来自多个线程的请求 −


步骤 1 - 创建客户端连接池管理器

通过实例化 PoolingHttpClientConnectionManager 类来创建客户端连接池管理器。

PoolingHttpClientConnectionManager connManager = new
   PoolingHttpClientConnectionManager(); 

步骤 2 - 设置最大连接数

使用 setMaxTotal() 方法设置池中的最大连接数。

//Set the maximum number of connections in the pool
connManager.setMaxTotal(100); 

步骤 3 - 创建一个 ClientBuilder 对象

通过使用 setConnectionManager() 方法设置连接管理器来创建一个 ClientBuilder 对象,如下所示 −

HttpClientBuilder clientbuilder =
HttpClients.custom().setConnectionManager(connManager);

步骤 4 - 创建 HttpGet 请求对象

通过将所需的 URI 作为参数传递给其构造函数来实例化 HttpGet 类。

HttpGet httpget1 = new HttpGet("URI1");
HttpGet httpget2 = new HttpGet("URI2");
. . . . . . . . . . . . 

步骤 5 - 实现 run 方法

确保您已经创建了一个类,使其成为线程(通过扩展线程类或通过实现 Runnable 接口)并实现了 run 方法。

public class ClientMultiThreaded extends Thread {
   public void run() {
      //Run method implementation . . . . . . . . . .
   }
}

步骤 6 - 创建线程对象

通过实例化上面创建的Thread类(ClientMultiThreaded)来创建线程对象。

将一个 HttpClient 对象、相应的 HttpGet 对象和一个表示 ID 的整数传递给这些线程。

ClientMultiThreaded thread1 = new ClientMultiThreaded(httpclient,httpget1, 1);
ClientMultiThreaded thread2 = new ClientMultiThreaded(httpclient,httpget2, 2);
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

步骤 7 - 启动并加入线程

使用 start() 方法启动所有线程并使用 join method() 方法加入它们。

thread1.start();
thread2.start();
. . . . . . . .
thread1.join();
thread2.join();
. . . . . . . . . . . .

步骤 8 - run 方法实现

在 run 方法中,执行请求,检索响应并打印结果。


示例

以下示例演示了同时从多个线程执行 HTTP 请求。 在此示例中,我们尝试执行来自不同线程的各种请求并尝试打印状态以及每个客户端读取的字节数。

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.w3ccoo.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();
   }
}

输出

执行时,上述程序生成以下输出 −

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