CountDownLatch實現(xiàn)并發(fā)請求

1.URL工具類

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class HttpSender {

    public static void main(String[] args) {
    }

    /**
     * 向指定URL發(fā)送GET方法的請求
     */
    public static String sendGet(String url, String param) throws UnsupportedEncodingException, IOException {
        return sendGet(url, param, null);
    }
    public static String sendGet(String url, String param, Map<String, String> header) throws UnsupportedEncodingException, IOException {
        String result = "";
        BufferedReader in = null;
        String urlNameString = url + "?" + param;
        URL realUrl = new URL(urlNameString);
        // 打開和URL之間的連接
        URLConnection connection = realUrl.openConnection();
        //設置超時時間
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(15000);
        // 設置通用的請求屬性
        if (header!=null) {
            Iterator<Entry<String, String>> it =header.entrySet().iterator();
            while(it.hasNext()){
                Entry<String, String> entry = it.next();
                System.out.println(entry.getKey()+":::"+entry.getValue());
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        connection.setRequestProperty("accept", "*/*");
        connection.setRequestProperty("connection", "Keep-Alive");
        connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        // 建立實際的連接
        connection.connect();
        // 獲取所有響應頭字段
        Map<String, List<String>> map = connection.getHeaderFields();
        // 遍歷所有的響應頭字段
        for (String key : map.keySet()) {
            System.out.println(key + "--->" + map.get(key));
        }
        // 定義 BufferedReader輸入流來讀取URL的響應,設置utf8防止中文亂碼
        in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
        String line;
        while ((line = in.readLine()) != null) {
            result += line;
        }
        if (in != null) {
            in.close();
        }
        return result;
    }

    /**
     * 向指定 URL 發(fā)送POST方法的請求
     */
    public static String sendPost(String url, String param) throws UnsupportedEncodingException, IOException {
        return sendPost(url, param, null);
    }

    public static String sendPost(String url, String param, Map<String, String> header) throws UnsupportedEncodingException, IOException {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        URL realUrl = new URL(url);
        // 打開和URL之間的連接
        URLConnection conn = realUrl.openConnection();
        //設置超時時間
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(15000);
        // 設置通用的請求屬性
        if (header!=null) {
            for (Entry<String, String> entry : header.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        conn.setRequestProperty("accept", "*/*");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent",
                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        // 發(fā)送POST請求必須設置如下兩行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        // 獲取URLConnection對象對應的輸出流
        out = new PrintWriter(conn.getOutputStream());
        // 發(fā)送請求參數(shù)
        out.print(param);
        // flush輸出流的緩沖
        out.flush();
        // 定義BufferedReader輸入流來讀取URL的響應
        in = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), "utf8"));
        String line;
        while ((line = in.readLine()) != null) {
            result += line;
        }
        if(out!=null){
            out.close();
        }
        if(in!=null){
            in.close();
        }
        return result;
    }
}

2.測試類

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class CountExample {

    // 請求總數(shù)
    public static int clientTotal = 5000;

    // 同時并發(fā)執(zhí)行的線程數(shù)
    public static int threadTotal = 200;

    public static int count = 0;

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        //信號量,此處用于控制并發(fā)的線程數(shù)
        final Semaphore semaphore = new Semaphore(threadTotal);
        //閉鎖,可實現(xiàn)計數(shù)器遞減
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal ; i++) {
            executorService.execute(() -> {
                try {
                    //執(zhí)行此方法用于獲取執(zhí)行許可,當總計未釋放的許可數(shù)不超過200時,
                    //允許通行,否則線程阻塞等待,直到獲取到許可。
                     semaphore.acquire();
                    System.out.println(test());
                    

                } catch (Exception e) {
                    //log.error("exception", e);
                    e.printStackTrace();
                }finally {
                    //釋放許可
                    semaphore.release();
                    //閉鎖減一
                    countDownLatch.countDown();
                }

            });
        }
        countDownLatch.await();//線程阻塞,直到閉鎖值為0時,阻塞才釋放,繼續(xù)往下執(zhí)行
        executorService.shutdown();

    }

    private static String test() throws IOException {
        return HttpSender.sendGet("http://localhost:8888/captcha","");
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容