- 作者: 三十而立
- 时间:2009年9月09日 16:00:35
- 本文出自 “inthirties(三十而立)”博客,转载请务必注明作者和保留出处http://blog.youkuaiyun.com/inthirties/archive/2009/09/09/4536006.aspx
在互联网应用里,去相关的网站自动的获取一些信息,是很常见的一种应用
比如,我这里现在要实现的一个功能,就是明天定时去ebay,amazon两个网站,获取产品信息,
从而,为自动分析的商务引擎提供基础的运算数据。
这里由于需要提取的信息很多,商家太多,所以,需要threadpool来进行多线程的实现,这里
使用httpclient作为http的实现,用自己的组件jager来提供模板解析的功能通过模板来提取
指定页面信息,由于这里ebay和amazon会分析ip,如果一个ip访问过多的话,作为舞弊行为,
而拒绝你继续访问。
这也就是我们用threadpool来进行多线程的原因,这这里在每个线程里,都会去一个指定的网站
获取代理服务器的信息,然后根据提取以后的代理服务器的信息,通过程序的代理上ebay和amazon
这样也就不会发现舞弊的行为了。当一个ip失效,会switch到另一个代理ip继续。
threadpool的代码比较简单,在1.5里提供了一个ThreadPoolExecutor的类,这个类已经基本
实现了线程池的功能。
自己简单封装了一个ThreadPoolManager的类
代码如下
引用:
public class ThreadPoolManager
{
private static Log log = LogFactory.getLog(ThreadPoolManager.class);
private ThreadPoolManager()
{}
public static ThreadPoolManager newInstance()
{
return new ThreadPoolManager();
}
private ThreadPoolExecutor taskPool = null; // Thread pool used to hold running threads
private BlockingQueue taskQueue = null; // Blocking queue used to hold waiting threads
private int corePoolSize = 2;
private int maxPoolSize = 2;
private int queueSize = 4;
private long waitTime = 60;
public final static String THREADPOOL_POOLSIZE_KEY = "corePoolSize";
public final static String THREADPOOL_MAXSIZE_KEY = "maxPoolSize";
public final static String THREADPOOL_QUEUESIZE_KEY = "queueSize";
public final static String THREADPOOL_WAITTIME_KEY = "waitTime";
void init(Properties p)
{
corePoolSize = StringUtils.str2Int(p.getProperty(THREADPOOL_POOLSIZE_KEY), 2);
maxPoolSize = StringUtils.str2Int(p.getProperty(THREADPOOL_MAXSIZE_KEY), 2);
queueSize = StringUtils.str2Int(p.getProperty(THREADPOOL_QUEUESIZE_KEY), 2);
waitTime = StringUtils.str2Int(p.getProperty(THREADPOOL_WAITTIME_KEY), 60);
taskQueue = new ArrayBlockingQueue(queueSize);
taskPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, waitTime,
TimeUnit.SECONDS, taskQueue, new ThreadPoolExecutor.CallerRunsPolicy());
log.info("Initialize thread pool succeed. ThreadPool: corePoolSize = "
+ corePoolSize + ", queueSize = " + queueSize
+ ", maxPoolSize = " + maxPoolSize);
}
public void run(Runnable command)
{
this.taskPool.execute(command);
}
}
调用的方式
Sample 代码
引用:
public class HitJobStart
{
.....
public void start()
{
if(findProxies == null)
return;
ThreadPoolManager pm = ThreadPoolManager.newInstance();
Properties p = new Properties();
p.setProperty(pm.THREADPOOL_MAXSIZE_KEY, ""+concurrent);
p.setProperty(pm.THREADPOOL_POOLSIZE_KEY, ""+concurrent);
p.setProperty(pm.THREADPOOL_QUEUESIZE_KEY, ""+concurrent);
pm.init(p);
for(FindProxy fp:findProxies)
{
hit(fp, urls,
timeoutMillionSecond, pm);
}
}
private void hit(FindProxy fp, final String[] urls, final int timeout, ThreadPoolManager pm)
{
fp.load();
List<Proxy> ps = fp.getValidProxys();
for(final Proxy p : ps)
{
pm.run(new Runnable(){
public void run()
{
hit(p, urls, timeout);
}
});
}
}
....
}
这里调用的地方是
pm.run(new Runnable(){
public void run()
{
hit(p, urls, timeout);
}
});
这样就把一个线程压到线程池里了。
- 如果没有那句“三十而立”,三十岁的男人正可以轻轻松松
- 专业论坛 http://www.inthirties.com
- 技术博客 http://blog.youkuaiyun.com/inthirties
- 个人站点 http://blog.inthirties.com
- Oracle Mysql技术论坛| 打造实用的Oracle Mysql技术交流园地