欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

我們要使用java的HttpClient實(shí)現(xiàn)get請(qǐng)求抓取網(wǎng)頁(yè)是一件比較容易實(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請(qǐng)求時(shí)上面的方法也堪用。不過(guò)這種多線程請(qǐng)求是基于在每次調(diào)用get方法時(shí)創(chuàng)建一個(gè)HttpClient實(shí)例實(shí)現(xiàn)的。每個(gè)HttpClient實(shí)例使用一次即被回收。這顯然不是一種最優(yōu)的實(shí)現(xiàn)。

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

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

根據(jù)文檔稍稍調(diào)整下我們的get請(qǐng)求實(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/"));
  }
}

這樣就差不多了。不過(guò)對(duì)于我自己而言,我更喜歡httpclient的fluent實(shí)現(xiàn),比如我們剛才實(shí)現(xiàn)的http get請(qǐng)求完全可以這樣簡(jiǎn)單的實(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>

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

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

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

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

就這樣!

相關(guān)文章

  • resty upload無(wú)需依賴的文件上傳與下載

    resty upload無(wú)需依賴的文件上傳與下載

    這篇文章主要為大家介紹了resty upload中無(wú)需依賴的文件上傳與下載過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Java IO之字節(jié)輸入輸出流詳解

    Java IO之字節(jié)輸入輸出流詳解

    這篇文章主要為大家介紹了Java IO之字節(jié)輸入輸出流,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • 解決使用@ResponseBody后返回500錯(cuò)誤的問(wèn)題

    解決使用@ResponseBody后返回500錯(cuò)誤的問(wèn)題

    這篇文章主要介紹了解決使用@ResponseBody后返回500錯(cuò)誤的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Java BeanDefination接口詳細(xì)講解

    Java BeanDefination接口詳細(xì)講解

    BeanDefinition是spring里面bean的一個(gè)建模對(duì)象,就相當(dāng)于class對(duì)象是普通java對(duì)象的建模對(duì)象一樣??赡茉趕pring作用的各種業(yè)務(wù)場(chǎng)景中,class對(duì)象并不能完成spring對(duì)bean的抽象,所以弄了一個(gè)BeanDefinition作為bean的抽象建模對(duì)象
    2022-11-11
  • Java Swing實(shí)現(xiàn)簡(jiǎn)單的體重指數(shù)(BMI)計(jì)算器功能示例

    Java Swing實(shí)現(xiàn)簡(jiǎn)單的體重指數(shù)(BMI)計(jì)算器功能示例

    這篇文章主要介紹了Java Swing實(shí)現(xiàn)簡(jiǎn)單的體重指數(shù)(BMI)計(jì)算器功能,涉及Java Swing窗口組件布局、響應(yīng)及數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • Java優(yōu)化for循環(huán)嵌套的高效率方法

    Java優(yōu)化for循環(huán)嵌套的高效率方法

    這篇文章主要介紹了Java優(yōu)化for循環(huán)嵌套的高效率方法,幫助大家更好的提升java程序性能,感興趣的朋友可以了解下
    2020-09-09
  • 淺談一下Java中枚舉的用法

    淺談一下Java中枚舉的用法

    這篇文章主要介紹了淺談一下Java中枚舉的用法,枚舉是一個(gè)被命名的整型常數(shù)的集合,用于聲明一組帶標(biāo)識(shí)符的常數(shù),當(dāng)一個(gè)變量有幾種固定可能的取值時(shí),就可以將它定義為枚舉類型,需要的朋友可以參考下
    2023-04-04
  • Java中的阻塞隊(duì)列BlockingQueue使用詳解

    Java中的阻塞隊(duì)列BlockingQueue使用詳解

    這篇文章主要介紹了Java中的阻塞隊(duì)列BlockingQueue使用詳解,阻塞隊(duì)列是一種線程安全的數(shù)據(jù)結(jié)構(gòu),用于在多線程環(huán)境下進(jìn)行數(shù)據(jù)交換,它提供了一種阻塞的機(jī)制,當(dāng)隊(duì)列為空時(shí),消費(fèi)者線程將被阻塞,直到隊(duì)列中有數(shù)據(jù)可供消費(fèi),需要的朋友可以參考下
    2023-10-10
  • java實(shí)現(xiàn)http請(qǐng)求工具類示例

    java實(shí)現(xiàn)http請(qǐng)求工具類示例

    這篇文章主要介紹了java實(shí)現(xiàn)http請(qǐng)求工具類示例,需要的朋友可以參考下
    2014-05-05
  • Java forEach對(duì)原數(shù)組的操作過(guò)程

    Java forEach對(duì)原數(shù)組的操作過(guò)程

    forEach對(duì)于基本數(shù)據(jù)類型,是直接賦值,對(duì)于引用數(shù)據(jù)類型,是引用地址值,forEach遍歷時(shí),是創(chuàng)建的臨時(shí)變量,引用的數(shù)據(jù)地址,本文給大家介紹Java forEach對(duì)原數(shù)組的操作過(guò)程,感興趣的朋友一起看看吧
    2024-02-02

最新評(píng)論