最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用java的HttpClient實(shí)現(xiàn)多線程并發(fā)

 更新時間:2016年09月11日 15:23:08   投稿:hebedich  
這篇文章主要介紹了使用java的HttpClient實(shí)現(xiàn)多線程并發(fā)的相關(guān)資料,需要的朋友可以參考下

說明:以下的代碼基于httpclient4.5.2實(shí)現(xiàn)。

我們要使用java的HttpClient實(shí)現(xiàn)get請求抓取網(wǎng)頁是一件比較容易實(shí)現(xiàn)的工作:

  public static String get(String url) {
    CloseableHttpResponseresponse = null;
    BufferedReader in = null;
    String result = "";
    try {
      CloseableHttpClienthttpclient = HttpClients.createDefault();
      HttpGethttpGet = new HttpGet(url);
      response = httpclient.execute(httpGet);
 
      in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
      StringBuffersb = new StringBuffer("");
      String line = "";
      String NL = System.getProperty("line.separator");
      while ((line = in.readLine()) != null) {
        sb.append(line + NL);
      }
      in.close();
      result = sb.toString();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (null != response) response.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }

要多線程執(zhí)行g(shù)et請求時上面的方法也堪用。不過這種多線程請求是基于在每次調(diào)用get方法時創(chuàng)建一個HttpClient實(shí)例實(shí)現(xiàn)的。每個HttpClient實(shí)例使用一次即被回收。這顯然不是一種最優(yōu)的實(shí)現(xiàn)。

HttpClient提供了多線程請求方案,可以查看官方文檔的《 Pooling connection manager 》這一節(jié)。HttpCLient實(shí)現(xiàn)多線程請求是基于內(nèi)置的連接池實(shí)現(xiàn)的,其中有一個關(guān)鍵的類即PoolingHttpClientConnectionManager,這個類負(fù)責(zé)管理HttpClient連接池。在PoolingHttpClientConnectionManager中提供了兩個關(guān)鍵的方法:setMaxTotal和setDefaultMaxPerRoute。setMaxTotal設(shè)置連接池的最大連接數(shù),setDefaultMaxPerRoute設(shè)置每個路由上的默認(rèn)連接個數(shù)。此外還有一個方法setMaxPerRoute——單獨(dú)為某個站點(diǎn)設(shè)置最大連接個數(shù),像這樣:

   HttpHosthost = new HttpHost("locahost", 80);
   cm.setMaxPerRoute(new HttpRoute(host), 50);

根據(jù)文檔稍稍調(diào)整下我們的get請求實(shí)現(xiàn):

package com.zhyea.robin;
 
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.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class HttpUtil {
 
  private static CloseableHttpClienthttpClient;
 
  static {
    PoolingHttpClientConnectionManagercm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(20);
    cm.setDefaultMaxPerRoute(50);
    httpClient = HttpClients.custom().setConnectionManager(cm).build();
  }
 
  public static String get(String url) {
    CloseableHttpResponseresponse = null;
    BufferedReaderin = null;
    String result = "";
    try {
 
      HttpGethttpGet = new HttpGet(url);
      response = httpClient.execute(httpGet);
 
      in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
      StringBuffersb = new StringBuffer("");
      String line = "";
      String NL = System.getProperty("line.separator");
      while ((line = in.readLine()) != null) {
        sb.append(line + NL);
      }
      in.close();
      result = sb.toString();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (null != response) response.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }
 
  public static void main(String[] args) {
    System.out.println(get("https://www.baidu.com/"));
  }
}

這樣就差不多了。不過對于我自己而言,我更喜歡httpclient的fluent實(shí)現(xiàn),比如我們剛才實(shí)現(xiàn)的http get請求完全可以這樣簡單的實(shí)現(xiàn):

package com.zhyea.robin;
 
import org.apache.http.client.fluent.Request;
import java.io.IOException;
 
public class HttpUtil {
 
  public static String get(String url) {
    String result = "";
    try {
      result = Request.Get(url)
          .connectTimeout(1000)
          .socketTimeout(1000)
          .execute().returnContent().asString();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return result;
  }
 
  public static void main(String[] args) {
    System.out.println(get("https://www.baidu.com/"));
  }
}

我們要做的只是將以前的httpclient依賴替換為fluent-hc依賴:

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>fluent-hc</artifactId>
   <version>4.5.2</version>
</dependency>

并且這個fluent實(shí)現(xiàn)天然就是采用PoolingHttpClientConnectionManager完成的。它設(shè)置的maxTotal和defaultMaxPerRoute的值分別是200和100:

    CONNMGR = new PoolingHttpClientConnectionManager(sfr);
    CONNMGR.setDefaultMaxPerRoute(100);
    CONNMGR.setMaxTotal(200);

唯一一點(diǎn)讓人不爽的就是Executor沒有提供調(diào)整這兩個值的方法。不過這也完全夠用了,實(shí)在不行的話,還可以考慮重寫Executor方法,然后直接使用Executor執(zhí)行g(shù)et請求:

Executor.newInstance().execute(Request.Get(url))
        .returnContent().asString();

就這樣!

相關(guān)文章

  • Java  Thread多線程詳解及用法解析

    Java Thread多線程詳解及用法解析

    本文主要介紹Java 多線程詳解及用法,這里整理了詳細(xì)資料及簡單實(shí)現(xiàn)代碼,有需要的小伙伴可以參考下
    2016-09-09
  • 關(guān)于log4j日志擴(kuò)展---自定義PatternLayout

    關(guān)于log4j日志擴(kuò)展---自定義PatternLayout

    這篇文章主要介紹了關(guān)于log4j日志擴(kuò)展---自定義PatternLayout,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java多線程的實(shí)現(xiàn)方式比較(兩種方式比較)

    Java多線程的實(shí)現(xiàn)方式比較(兩種方式比較)

    Java多線程實(shí)現(xiàn)方式有兩種,第一種是繼承Thread類,第二種是實(shí)現(xiàn)Runnable接口,兩種有很多差異,下面跟著本文一起學(xué)習(xí)吧
    2015-11-11
  • springboot整合sa-token中的redis報netty錯誤問題

    springboot整合sa-token中的redis報netty錯誤問題

    整合Spring Boot與sa-token-redis-jackson時遇到Netty版本沖突,通過將netty-common升級到與sa-token-redis-jackson兼容的版本4.1.79解決
    2024-11-11
  • 關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案

    關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案

    這篇文章主要介紹了關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java LinkedList的實(shí)例詳解

    java LinkedList的實(shí)例詳解

    這篇文章主要介紹了java LinkedList的實(shí)例詳解的相關(guān)資料,通過本文希望大家能徹底了解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • Springboot @Import 詳解

    Springboot @Import 詳解

    這篇文章主要介紹了Springboot @Import 詳解,仔細(xì)看了下Springboot關(guān)于@Import的處理過程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • SpringBoot自動裝配之@Enable深入講解

    SpringBoot自動裝配之@Enable深入講解

    這篇文章主要介紹了SpringBoot自動裝配之@Enable,SpringBoot中提供了很多Enable開頭的注解,這些注解都是用于動態(tài)啟用某些功能的。而其底層原理是使用@Import注?解導(dǎo)入一些配置類,實(shí)現(xiàn)Bean的動態(tài)加載
    2023-01-01
  • Spring Boot 中的 CommandLineRunner 原理及使用示例解析

    Spring Boot 中的 CommandLineRunner 原理及使用示例

    CommandLineRunner 是 Spring Boot 提供的一個非常有用的接口,可以幫助你在應(yīng)用程序啟動后執(zhí)行初始化任務(wù),本文通過多個示例詳細(xì)介紹了如何在實(shí)際項目中使用 CommandLineRunner,感興趣的朋友一起看看吧
    2025-04-04
  • Spring源碼解析之Configuration

    Spring源碼解析之Configuration

    今天帶大家來學(xué)習(xí)Java Spring相關(guān)知識,文中對Configuration源碼介紹的非常詳細(xì),有非常多的圖文解說及代碼示例,對正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05

最新評論

革吉县| 新疆| 佛坪县| 墨竹工卡县| 彩票| 江陵县| 民权县| 嵊泗县| 若羌县| 仙游县| 荔浦县| 抚顺市| 寻乌县| 焦作市| 大姚县| 凤庆县| 延庆县| 社会| 嵩明县| 通州区| 浪卡子县| 托克托县| 朝阳市| 冀州市| 色达县| 简阳市| 绿春县| 吉隆县| 襄城县| 奉贤区| 清苑县| 江安县| 西城区| 湖北省| 达尔| 衡阳县| 汽车| 河源市| 都匀市| 白城市| 元朗区|