在JAVA中发出多个http请求的快速异步方法

在JAVA中发出多个http请求的快速异步方法,java,multithreading,performance,asynchronous,httprequest,Java,Multithreading,Performance,Asynchronous,Httprequest,我有一个程序,可以发出非常快速的http请求。请求应该异步进行,这样它就不会阻塞主线程 因此,我创建了一个队列,由10个发出http请求的独立线程观察。如果队列中插入了某些内容,那么获取数据的第一个线程将发出请求并处理结果 队列中充满了数千个项目,因此,为了尽可能快地获得响应,确实需要多线程 因为我有很多代码,所以我将给出一个简短的示例 主类 package fasthttp; import java.util.concurrent.ExecutorService; import java.u

我有一个程序,可以发出非常快速的http请求。请求应该异步进行,这样它就不会阻塞主线程

因此,我创建了一个队列,由10个发出http请求的独立线程观察。如果队列中插入了某些内容,那么获取数据的第一个线程将发出请求并处理结果

队列中充满了数千个项目,因此,为了尽可能快地获得响应,确实需要多线程

因为我有很多代码,所以我将给出一个简短的示例

主类

package fasthttp;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class FastHTTP {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            LinkedBlockingQueue queue = new LinkedBlockingQueue();
            queue.add("http://www.lennar.eu/ip.php");//for example
            executor.execute(new HTTPworker(queue));
        }
    }

}
package fasthttp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.LinkedBlockingQueue;

public class HTTPworker implements Runnable {

    private final LinkedBlockingQueue queue;

    public HTTPworker(LinkedBlockingQueue queue) {        
        this.queue = queue;
    }

    private String getResponse(String url) throws IOException {

        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        StringBuilder response;
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()))) {
            String inputLine;
            response = new StringBuilder();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
        }
        return response.toString();
    }

    @Override
    public void run() {
        while (true) {
            try {
                String data = (String) queue.take();
                String response = getResponse(data);
                //Do something with response
                System.out.println(response);
            } catch (InterruptedException | IOException ex) {
                //Handle exception
            }
        }
    }
}

有没有更好或更快的方法来异步处理数千个http请求的响应?我追求的是速度和性能。

回答我自己的问题。尝试了Apaches异步http客户端,但过了一段时间,我开始使用Ning的异步客户端,我对它很满意。

回答我自己的问题。尝试了Apaches异步http客户端,但过了一段时间,我开始使用Ning的异步客户端,我对此感到满意。

import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import org.apache.http.client.methods.HttpGet;

import java.util.Iterator;

import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

public class RestService {
    private final static Executor executor = Executors.newCachedThreadPool();
    private final static CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build();

    public static String sendSyncGet(final String url) {
        return sendAsyncGet(List.of(url)).get(0);
    }

    public static List<String> sendAsyncGet(final List<String> urls){
        List<GetRequestTask> tasks = urls.stream().map(url ->  new GetRequestTask(url, executor)).collect(Collectors.toList());
        List<String> responses = new ArrayList<>();
        while(!tasks.isEmpty()) {
            for(Iterator<GetRequestTask> it = tasks.iterator(); it.hasNext();) {
                final GetRequestTask task = it.next();
                if(task.isDone()) {
                    responses.add(task.getResponse());
                    it.remove();
                }
            }
            //if(!tasks.isEmpty()) Thread.sleep(100); //avoid tight loop in "main" thread
        }
        return responses;
    }

    private static class GetRequestTask {
        private final FutureTask<String> task;

        public GetRequestTask(String url, Executor executor) {
            GetRequestWork work = new GetRequestWork(url);
            this.task = new FutureTask<>(work);
            executor.execute(this.task);
        }

        public boolean isDone() {
            return this.task.isDone();
        }

        public String getResponse() {
            try {
                return this.task.get();
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    private static class GetRequestWork implements Callable<String> {
        private final String url;

        public GetRequestWork(String url) {
            this.url = url;
        }
        public String getUrl() {
            return this.url;
        }
        public String call() throws Exception {
            return closeableHttpClient.execute(new HttpGet(getUrl()), new BasicResponseHandler());
        }
    }
}
导入java.util.List; 导入java.util.concurrent.*; 导入java.util.stream.collector; 导入org.apache.http.client.methods.HttpGet; 导入java.util.Iterator; 导入org.apache.http.impl.client.BasicResponseHandler; 导入org.apache.http.impl.client.CloseableHttpClient; 导入org.apache.http.impl.client.HttpClientBuilder; 公共类服务{ private final static Executor Executor=Executors.newCachedThreadPool(); 私有最终静态CloseableHttpClient CloseableHttpClient=HttpClientBuilder.create().build(); 公共静态字符串sendSyncGet(最终字符串url){ 返回sendAsyncGet(url的列表)).get(0); } 公共静态列表sendAsyncGet(最终列表URL){ List tasks=url.stream().map(url->new GetRequestTask(url,executor)).collect(Collectors.toList()); 列表响应=新建ArrayList(); 而(!tasks.isEmpty()){ for(Iterator it=tasks.Iterator();it.hasNext();){ final GetRequestTask task=it.next(); if(task.isDone()){ add(task.getResponse()); it.remove(); } } //if(!tasks.isEmpty())Thread.sleep(100);//避免“主”线程中的紧循环 } 回应; } 私有静态类GetRequestTask{ 私人最终未来任务; 公共GetRequestTask(字符串url,执行器执行器){ GetRequestWork=新的GetRequestWork(url); this.task=新的未来任务(工作); executor.execute(本任务); } 公共布尔isDone(){ 返回此.task.isDone(); } 公共字符串getResponse(){ 试一试{ 返回此.task.get(); }捕获(例外e){ 抛出新的运行时异常(e); } } } 私有静态类GetRequestWork实现可调用{ 私有最终字符串url; 公共GetRequestWork(字符串url){ this.url=url; } 公共字符串getUrl(){ 返回this.url; } 公共字符串调用()引发异常{ 返回closeableHttpClient.execute(newHttpGet(getUrl()),newBasicResponseHandler()); } } }
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.*;
导入java.util.stream.collector;
导入org.apache.http.client.methods.HttpGet;
导入java.util.Iterator;
导入org.apache.http.impl.client.BasicResponseHandler;
导入org.apache.http.impl.client.CloseableHttpClient;
导入org.apache.http.impl.client.HttpClientBuilder;
公共类服务{
private final static Executor Executor=Executors.newCachedThreadPool();
私有最终静态CloseableHttpClient CloseableHttpClient=HttpClientBuilder.create().build();
公共静态字符串sendSyncGet(最终字符串url){
返回sendAsyncGet(url的列表)).get(0);
}
公共静态列表sendAsyncGet(最终列表URL){
List tasks=url.stream().map(url->new GetRequestTask(url,executor)).collect(Collectors.toList());
列表响应=新建ArrayList();
而(!tasks.isEmpty()){
for(Iterator it=tasks.Iterator();it.hasNext();){
final GetRequestTask task=it.next();
if(task.isDone()){
add(task.getResponse());
it.remove();
}
}
//if(!tasks.isEmpty())Thread.sleep(100);//避免“主”线程中的紧循环
}
回应;
}
私有静态类GetRequestTask{
私人最终未来任务;
公共GetRequestTask(字符串url,执行器执行器){
GetRequestWork=新的GetRequestWork(url);
this.task=新的未来任务(工作);
executor.execute(本任务);
}
公共布尔isDone(){
返回此.task.isDone();
}
公共字符串getResponse(){
试一试{
返回此.task.get();
}捕获(例外e){
抛出新的运行时异常(e);
}
}
}
私有静态类GetRequestWork实现可调用{
私有最终字符串url;
公共GetRequestWork(字符串url){
this.url=url;
}
公共字符串getUrl(){
返回this.url;
}
公共字符串调用()引发异常{
返回closeableHttpClient.execute(newHttpGet(getUrl()),newBasicResponseHandler());
}
}
}

如果您在负载测试中需要此功能,请使用JMeterApache、Jersey和许多其他支持异步HTTP请求的项目。例如,见。谷歌搜索“Java异步”