现在项目(web)中有个需求,每天临晨对一个 WEB 目标进行页面爬取,爬取过程是一个多线程任务,这个任务由 Quartz(Spring2 整合)cronTrigger 来调度。 大概同时会派出5-10个爬虫线程,执行爬虫线程的线程池,也是由 Spring 配置的 SimpleThreadPoolTaskExecutor。
现在的情况:众所周知,Quartz 缺省维持了一组自己的线程池,default pool size = 10。 实际上我全系统只有一个任务,每天运行一次,那么,每次调度触发时,池中始终只有一个线程会被用到。 这个线程开始执行任务后, 单独配置的爬虫线程池再接着开始执行爬取任务。
--------------------
在互联网应用里,去相关的网站自动的获取一些信息,是很常见的一种应用
比如,我这里现在要实现的一个功能,就是明天定时去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);
}
});
这样就把一个线程压到线程池里了。
分享到:
相关推荐
总之,"Quartz多线程示例"是一个很好的学习资源,它教你如何利用Quartz的多线程能力来并发执行任务,以及如何根据需求定制调度策略。通过这个示例,你可以深入理解Quartz的内部工作原理,提升你在Java应用中处理定时...
Quartz是一款开源的作业调度框架,它允许开发者创建和安排任务执行。在Java应用程序中,Quartz能够帮助我们在特定的时间点或按照预设的周期执行某些功能,如数据收集、日志清理等。当我们需要终止某个正在运行的任务...
Java定时执行多任务是软件开发中的常见需求,用于在特定时间点或按固定频率执行某项操作,例如数据同步、日志清理等。Java提供了一些内置的定时工具,如`java.util.Timer`和`java.util.concurrent....
在多应用服务器负载均衡环境下,Spring Quartz定时任务的重复执行问题是一个常见的挑战。Spring Quartz是一个强大的、开源的作业调度框架,允许开发者定义和执行复杂的定时任务。然而,当多个服务器实例并行运行时,...
1. **并发问题**:当多个线程同时尝试修改同一个任务的状态时,可能会出现并发问题。因此,在实现动态加载机制时,需要注意对数据库操作进行适当的同步控制。 2. **性能优化**:频繁地从数据库中读取配置信息可能会...
**执行多个任务**:只需要为每个任务创建不同的`JobDetail`和`Trigger`,并确保它们的名称不重复。然后将它们添加到同一个调度器,调用`Start()`即可。注意,所有任务调度器创建完成后,只需要调用一次`Start()`。 ...
总的来说,Spring集成Quartz提供了灵活的定时任务解决方案,但同时需要注意避免配置错误和并发问题,以防止任务被执行多次。通过理解Quartz的工作原理和Spring的定时任务API,我们可以有效地管理定时任务,确保它们...
4. **并行执行**:默认情况下,Quartz允许多个Job并行执行,只要它们不在同一组或满足并行执行的条件。如果需要限制同一组内的并行执行,可以通过设置Scheduler的属性`org.quartz.threadPool.class`为`org.quartz....
在实际项目中,有时我们需要判断一个Quartz任务是否正在运行,以便进行相应的操作,如避免重复执行或者进行状态监控。本文将详细介绍如何在Quartz中实现这一功能。 首先,理解Quartz的工作原理是关键。Quartz通过...
在C#中,多线程技术是实现并发执行任务的关键。在本项目中,多线程被用来确保进程监控任务与其他应用程序组件并行运行,提高程序效率。 Quartz.NET是一个强大的、完全开源的作业调度框架,它允许开发者定义“作业”...
- 注意处理Web容器的多线程环境,确保任务的线程安全。 4. **CronTrigger与Cron表达式** - CronTrigger允许按照特定的时间模式触发任务,比如每分钟、每天的某个时间等。 - Cron表达式由7个子表达式组成,分别...
Quartz的主要功能在于允许开发者安排任务在特定的时间点或按照预定的周期执行。这在很多场景下都非常有用,例如数据备份、日志清理、发送通知等。Quartz的核心组件包括Scheduler、Job、Trigger和Calendar。 1. ...
7. **并发与线程管理**:Quartz使用多线程机制来并行执行任务,同时提供了线程池管理,可以根据需要调整线程数量,优化资源利用。 8. **作业商店(Job Store)**:Quartz提供了多种作业商店,如RAMJobStore(内存...
Quartz具有高度的可扩展性,支持多线程和分布式环境,适用于大型企业级应用。 2. **Cron表达式** Cron表达式是Quartz中用于定义触发器时间规则的重要工具,源自Unix的crontab命令。它由六个或七个字段组成,每个...
- **多线程与并发**:Quartz使用多线程机制执行任务,确保任务的并发执行,提高系统效率。 - **集群支持**:Quartz支持多个服务器实例形成集群,当一个服务器实例故障时,其他实例能接管任务执行,提供高可用性。 ...
Quartz是一款开源的作业调度框架,它允许开发者创建、调度和执行各种类型的任务。在分布式环境中,Quartz的集群功能可以实现高可用性和任务的负载均衡。以下是对"quartz支持集群的定时器任务"这一主题的详细阐述。 ...
Quartz是一款开源的作业调度框架,它允许开发者创建、调度和执行作业,这些作业可以是任何Java类。在Java开发中,Quartz常用于实现定时任务,...同时,也可以借此机会学习Java多线程和并发控制的知识,提升编程技能。
它支持多线程执行,可以同时处理多个作业,也可以根据需要调整线程池大小。此外,Quartz.NET还允许你暂停、恢复或重新调度作业,以适应业务需求的变化。 总之,Quartz.NET为.NET开发者提供了一个强大的工具,帮助...
5. **多线程与多进程**:APScheduler支持多线程和多进程模型,可以根据需要选择合适的执行方式,以充分利用系统的资源,同时保证任务执行的并发性。 6. **插件机制**:APScheduler有一个插件系统,可以扩展其功能,...
总之,Quartz是Java应用程序实现定时任务的强大工具,其线程管理功能使得开发者能够灵活地控制任务执行的并发性和顺序。这份7页的文档可能详细介绍了如何配置和利用Quartz进行线程管理和任务调度,对于想要深入理解...