`
san_yun
  • 浏览: 2653706 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

几种http请求的实现方式

 
阅读更多
需要在程序中访问一批url,类似爬虫的东西,想了几种方案:

1. 同步执行
for循环一条条抓取,这种方式最简单但效率最差,遇到网站响应慢的url会阻塞掉后面的执行。


2.异步方式
每个url开一个进程来处理:

String[] urls = { "url1", "url2", "url3", "url4", "url5", "url6",
				"url7" };
for (String url : urls) {
 
Thread t = new Thread(new Runnable(){
   
    public void run(){
        //fetch site
     }

})
}
t.start()


这种方式能利用多线程同时并发http请求,最大的提高吞吐量。但这种方案也有问题:
1. 多少个图片就开多少个线程,线程数不可控,如果是一万张图片就启动一万个thread,明显资源有问题。
2. 大量启动线程也有性能消耗。

3. 使用线程池
通过配置线程池来做到资源可控。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadPool {

	private List<Thread> threads = new ArrayList<Thread>();

	private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(20);

	public ThreadPool(int size) {
		for (int i = 0; i < size; ++i) {
			Thread thread = new Thread(new Worker(queue));
//			thread.setDaemon(true);
			thread.start();
			threads.add(thread);
		}
	}

	public void sumbit(Runnable runnable) {
		queue.add(runnable);
	}

	
	private static class Worker implements Runnable {

		private BlockingQueue<Runnable> queue;

		public Worker(BlockingQueue<Runnable> queue) {
			super();
			this.queue = queue;
		}

		@Override
		public void run() {
			while (true) {

				Runnable runnable = queue.poll();
				if(runnable!=null){
					runnable.run();
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}
}

public class ThreadPoolFetcher {

	public static void main(String[] args) {
		ThreadPool pool = new ThreadPool(7);
		String[] urls = { "url1", "url2", "url3", "url4", "url5", "url6",
				"url7" };

		for (String url : urls) {
			pool.sumbit(new Fetcher(url));
		}
		

	}

	private static class Fetcher implements Runnable {
		private String url;

		public Fetcher(String url) {
			super();
			this.url = url;
		}

		public void run() {

			System.out.println(Thread.currentThread().getName() + ":" + url);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

这种方式利用生产者消费者的方式来实现线程池,做到资源可控。
不过这种方式有点问题是,执行完成之后线程池里的线程不会退出。

4. 使用Executors轻松搞定:
最后还是使用jdk5提供的Executors轻松搞定吧:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Fetcher {

	public static void main(String[] args) throws InterruptedException {
		
		String[] urls = {"url1","url2","url3","url4","url5","url6","url7"};
		ExecutorService exs =  Executors.newFixedThreadPool(100);
		List<Callable<String>> tasks = new ArrayList<Callable<String>>();
		for(String url :urls){
			tasks.add(new FetchImageTask(url));
		}
		exs.invokeAll(tasks);
		System.out.println("end");
		exs.shutdown();
	}
	
	
	/**
	 * @author yunpeng
	 *
	 */
	private static  class FetchImageTask implements Callable<String>{
		
		private String url;
		
		public FetchImageTask(String url) {
			super();
			this.url = url;
		}
		@Override
		public String call() throws Exception {
			System.out.println(Thread.currentThread().getName());
			 Thread.sleep(3000);
			return "ok"+url;
		}
	}
}



分享到:
评论

相关推荐

    C++实现HTTP请求

    在C++中实现HTTP请求,我们通常需要处理以下几个核心部分: 1. **建立连接**:使用socket编程创建一个套接字,并通过connect函数与指定的服务器建立TCP连接。这涉及到IP地址解析和端口绑定等操作。 2. **构建请求...

    c#使用Socket发送HTTP/HTTPS请求的实现代码

    "C#使用Socket发送HTTP/HTTPS请求的实现代码" C#中使用Socket发送HTTP/HTTPS请求是一种高效的方法,特别是在需要自定义HTTP封包或对HTTP请求进行深入控制时。本文主要介绍了如何使用C#的Socket类来发送HTTP/HTTPS...

    Spring MVC请求映射常见的三种方式

    本文将详细探讨Spring MVC中常见的三种请求映射方式:基于注解的映射、基于XML配置的映射以及基于Java配置的映射。我们将深入理解每种方式的工作原理,并通过实例来展示其用法。 ### 1. 基于注解的映射 **注解驱动...

    自己封装的C#实现HTTP请求的动态链接库,dll

    标题中的“自己封装的C#实现HTTP请求的动态链接库,dll”指的是使用C#编程语言编写的HTTP客户端库,该库被封装成一个动态链接库(DLL)文件,供其他应用程序调用,以实现HTTP协议的网络通信功能。DLL是一种可重用的...

    自己实现的Json和简单HTTP请求(C++ Builder 平台)

    在C++ Builder中,你可以使用低级别的套接字API来实现HTTP请求,或者使用第三方库如libcurl简化这一过程。 在提供的`untJSON.cpp`和`untJSON.h`文件中,可能包含了上述JSON和HTTP请求的实现。这些源代码可能定义了...

    android开发网络请求的几种方式

    本文将详细介绍Android开发中常用的几种网络请求方式,并以GET和POST请求为例进行具体说明。 #### 一、Android网络请求的基础概念 在开始介绍具体的请求方式之前,我们先来了解一些基本概念。 - **HTTP...

    angularjs中$http请求的几种写法

    ### AngularJS中$http请求的多种实现方式 在AngularJS中,`$http`服务是用于与后端服务器进行通信的强大工具。它支持多种HTTP请求类型(GET、POST、PUT、DELETE等),并且提供了灵活的方式来配置这些请求。本文将...

    Vue 利用指令实现禁止反复发送请求的两种方法

    实现方式也有好几种:  1、在按钮点击发起请求后,弹个蒙层,显示个loading,等请求数据返回了将蒙层隐藏掉。  2、在按钮点击发起请求后,将按钮禁用掉,同样等数据返回了将按钮禁用解除。  以上是比较常见的2种...

    Axis客户端的几种实现方式

    标题中的“Axis客户端的几种实现方式”指的是在Java开发中,使用Axis库来创建和使用Web服务客户端的不同方法。Axis是Apache软件基金会的一个开源项目,它提供了一个强大的工具集,用于处理SOAP(简单对象访问协议)...

    跨域请求的几种方式

    ### 跨域请求的几种方式 #### 一、前言 在现代Web开发中,由于浏览器的安全机制——同源策略,对于跨域请求的支持成为了一个常见的需求。所谓跨域,是指当请求的目标URL与当前页面地址在协议、域名、端口三者中...

    TCP实现http请求

    TCP实现HTTP请求的过程可以分为以下几个步骤: 1. 建立连接:客户端浏览器向服务器发送连接请求,服务器响应连接请求,建立连接。 2. 客户端请求:客户端浏览器发送HTTP请求到服务器,包括请求行、请求头部、空行和...

    C++编写的Linux下Http请求

    本篇将深入探讨使用C++在Linux环境下实现HTTP请求,包括GET和POST方法。 HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器的传输协议。它是一个基于请求与...

    浅谈PHP发送HTTP请求的几种方式

    PHP 开发中我们常用 cURL 方式封装 HTTP 请求,什么是 cURL? cURL 是一个用来传输数据的工具,支持多种协议,如在 Linux 下用 curl 命令行可以发送各种 HTTP 请求。PHP 的 cURL 是一个底层的库,它能根据不同协议跟...

    java实现http请求以及解析json与java对象转换 项目源代码实例

    在Java中,可以通过多种方式实现HTTP请求,例如使用`java.net.URL`和`java.net.HttpURLConnection`类,或者使用Apache HttpClient库。这个项目源代码可能包含了使用这些方法之一的例子,展示如何发送GET、POST以及...

    JavaEE实现登录功能的几种框架组合方式

    本文将探讨几种常见的框架组合方式,以帮助开发者高效且安全地完成这一任务。 1. **Servlet + JSP** 最基础的方式是直接使用Servlet和JSP(JavaServer Pages)来处理用户请求和展示页面。Servlet负责后端逻辑,如...

    WebService调用的几种方式

    本文将深入探讨在Java环境中调用WebService的五种主要方式:Axis、CXF、HttpClient、MyEclipse反向生成以及XFire。 1. Axis:Apache Axis是最早且广泛使用的SOAP库,用于创建和消费Web服务。使用Axis调用WebService...

    jquery实现Ajax请求的几种常见方式总结

    本文实例讲述了jquery实现Ajax请求的几种常见方式。分享给大家供大家参考,具体如下: 用原生的javascript开发ajax有着许多重复的代码,当然你也可以封装成可以复用的js代码,但却不一定那么通用。但jquery 提供的...

    如何伪造IP 发送HTTP请求request

    这是一种DDoS(分布式拒绝服务)攻击方式,伪造IP的SYN请求会淹没目标服务器,使其无法正常处理合法连接。 6. **网络编程和源码**:"封装了HTTP操作的类,支持代理服务 - VC 源码 - 网络编程"提供了实现此类功能的...

    redis实现加锁的几种方法示例详解

    本文主要给大家介绍了关于redis实现加锁的几种方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 1. redis加锁分类 redis能用的的加锁命令分表是INCR、SETNX、SET 2. 第一种锁命令INCR 这种...

    模拟HTTP请求工具

    HTTP请求由几部分组成:方法(如GET、POST)、URL、HTTP头和可选的请求体。响应则包含状态码、响应头和响应体。 二、模拟请求工具的功能 1. 发送不同类型的HTTP请求:模拟请求工具能模拟多种HTTP方法,包括GET、...

Global site tag (gtag.js) - Google Analytics