在JAVA中发出多个http请求的快速异步方法
我有一个程序,可以发出非常快速的http请求。请求应该异步进行,这样它就不会阻塞主线程 因此,我创建了一个队列,由10个发出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
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异步”