事情的起因是因为我要在一个定时任务的某处将数据入库,一个是批量入库,之后再是非批量的普通方式入库,伪代码如下:
for(int i=0; i<n; i++) { //批量入库 pools.execute(new BatchSaveThread(list));//list为map集合 //普通入库 pools.execute(new SaveThread(map)); }
这个定时任务是每隔1min就触发的,频率还蛮高。而且n大约是10,pools为线程池,BatchSaveThread和SaveThread分别为批量入库的线程和普通入库的线程。
问题现象:这个定时任务放到环境上跑,发现过个5-7min就会“卡死”,即:批量入库或普通入库都不能持续,普通入库在持续最多7分钟左右就不再进行了。debug发现普通入库的线程会进入,但是就是没法往下执行。
解决:其实可以从线程的角度考虑,之前想在定时任务当中,用线程池调配线程的方式异步地入库,但由于批量入库的步骤可能需要的时间较长,所以线程在此处耗费时间较多,以至于在本分钟内没能完成,卡在这导致普通入库那一步也没有完成。
把普通入库和批量入库分为2个定时任务,一前一后的执行。普通入库先执行,在那里for循环中负责生成每次跟循环有关的list,并把他们放到内存中,之后,在晚些时候执行批量入库,再在批量入库的定时任务中for循环,取出每次的list,再针对该List入库。为进一步避免线程问题,可以摈弃异步入库,直接取代原来的入库线程而调用dao的相关入库方法,,后来发现其实也并没有消耗太多时间。
注:
1)内存存取list可以使用ServletContext的setAttribute(String key, Object obj)和getAttribute(key);取完可以removeAttribute(String key)减少内存占用~~;key的设计可以带上for循环里的元素以及时间。
2)mysql中想要真正的executeBatch()起作用,要记得在jdbc的url上加上rewriteBatchedStatements=true才行,否则批量执行是不会起作用的。
改进之后,经过长时间测试发现,无论是数据量较大的批量入库,还是普通入库,都能平稳地运行下去了。
顺便补充些小问题:
1.循环一个集合的前提是这个集合不为null,虽然默认情况下是根本不用考虑的,但如果你是通过本例中ServletContext的getAttribute(String key)这种方式,或其他方式得到List——即不是通过常见的定义方式得到的List,在循环它之前,需要做容错处理:if(list != null)再循环哦!
2.在一个定时任务类的属性定义上不要直接带上需要通过bean得到的其他bean类,否则会报空指针异常。比如我在一个定时任务类的的属性上(方法外)这样:
WebApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
或这样:
Dao dao = bean.get(xxxx)
都会报NullPointerException。之所以不能在方法体外的类属性上直接定义这些,是因为:定时任务类也是被配置成bean的,在Spring容器启动成功之前,整个Spring容器的环境是还未完全搭建成功的,而bean的这些属性会在把它管理之前就扫描到,所以你不能在还未完全搭建Spring环境成功就使用Spring的上下文。——这点需注意,可以延伸到任何一个需要被管理的bean,不能在方法体外部直接使用Spring上下文。
相关推荐
总结起来,"JAVA 基于SpringBoot+layui秒级定时任务管理"项目旨在利用Spring Boot的定时任务能力以及layui的前端组件,构建一个可高效管理和监控的定时任务系统。通过这样的系统,开发者可以方便地创建、修改和查看...
"多子系统"意味着一个复杂应用被拆分成多个独立的模块,每个模块专注于特定功能。这样做的好处包括模块间的解耦、易于维护和扩展。子系统间通过API进行通信,例如使用RESTful API或消息队列,以确保系统的稳定性和可...
Go-gocron是一款基于Go语言实现的轻量级定时任务集中调度和管理系统,设计目标是为了解决在分布式系统中对定时任务的管理和调度问题。它提供了一个简单易用的API,可以方便地在Go应用中集成定时任务,且无需依赖外部...
ASP.NET定时任务是一种在Web应用程序中执行预定任务的技术,它允许开发者在特定时间或间隔执行某些操作,如数据同步、日志清理、发送邮件等。ASP.NET提供了多种方式来实现定时任务,包括System.Threading.Timer、...
开发者可以创建一个带有`@Scheduled`注解的方法,设置执行周期,如cron表达式,来实现定时执行的任务。例如: ```java import org.springframework.scheduling.annotation.Scheduled; import org.springframework....
该项目为台风定时入库数据源接口的Python实现,包含612个文件,其中Python源代码文件540个,PNG图片文件32个,YAML配置文件17个,文本文件7个,Excel文件2个,批处理文件2个,覆盖率报告1个,Git忽略文件1个,dist-...
### 重要知识点总结 #### 一、在线考试系统的设计与实现 **项目名称:** 在线考试系统的设计与实现 ...对于Java Web开发者而言,通过参与这些项目的实践,不仅能够提升自己的技术水平,还能增强解决实际问题的能力。
不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程...
因数据库同步太耗网络资源,同步数据不多可采取产生SQL同步的方式,这个小程序,可以定时读取指定SQL文件连接数据库并执行的功能,配合ftp下载或推送就可实现同步。 采用ADO方式连接,config.ini文件可设置连接字符...
C&C++编程项目:产品入库管理操作系统.zip C&C++编程项目:产品入库管理操作系统.zip C&C++编程项目:产品入库管理操作系统.zip C&C++编程项目:产品入库管理操作系统.zip C&C++编程项目:产品入库管理操作系统.zip ...
综合技能训练二:入库任务单分析
【入库单的制作过程及其...总结来说,制作入库单是一项重要的仓储作业,它涉及到多个部门的协同工作,是物流管理中的核心环节。通过深入学习入库单的制作,不仅可以提升物流操作的规范性,还能促进企业的整体运营效率。
在IT行业中,Google Guava库是一个非常强大的工具集,它为Java开发人员提供了一系列实用的集合、缓存、并发和I/O工具。本篇文章将详细探讨如何利用Guava库实现定时缓存功能,以提高应用的性能和效率。 首先,Guava...
这份登记表的重要性在于,它提供了整个营养改善项目运作的详细数据,有助于管理者监控项目的执行情况,及时发现和解决问题,如库存不足或分配不均等问题。同时,它也确保了项目的公正和透明,便于审计和评估。 总的...
总的来说,"Java Web项目企业进销存管理系统"是一个综合运用了Java Web技术的实例,展示了如何利用这些技术构建高效的企业管理工具。它融合了服务器端编程、数据库管理、用户认证、业务逻辑等多个方面的知识,对于...
基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决...
Oracle 数据库多语言入库问题的解决方案是针对企业在国际化进程中遇到的多国语言信息存储难题,尤其是在使用Oracle数据库时,由于字符集的不兼容性导致非中文语言数据入库时出现乱码。Oracle数据库作为全球广泛使用...
《基于PLC的车辆出入库管理系统...综上所述,基于PLC的车辆出入库管理系统设计是一个集硬件设计、软件编程和系统调试于一体的综合性项目,旨在通过自动化手段解决车辆管理中的实际问题,实现精细化、智能化的停车管理。
7. **项目结构**:虽然没有具体的代码展示,但一个小型项目通常会有明确的模块划分,例如一个单独的类负责定时任务,另一个处理PDF解析,还有专门的类处理数据库操作等。良好的代码组织有助于项目的可维护性和扩展性...
- **定义任务**:然后,你可以创建一个带有`@Component`注解的类,并在该类的方法上使用`@Scheduled`注解来声明定时任务。注解参数如`cron`用于设置cron表达式,或者`fixedDelay`、`fixedRate`用于设置固定延迟或...