java多线程文件处理和数据库批插入
我有一个Java主应用程序,它将逐行读取文件。每行代表订户数据
name, email, mobile, ...
为正在处理的每一行创建一个订户对象,然后使用JDBC将该对象持久化到数据库中
PS:输入文件大约有1500万用户数据,应用程序处理大约需要10-12小时。我需要将此任务减少到2-3小时左右,因为此任务是一项迁移活动,我们得到的停机时间约为4-5小时
我知道我需要使用多线程/线程池可能是Java的本机ExecuterService。但我也被要求做批量更新。假设使用50或100个工作线程的线程池,并批量更新500-1000个订阅者
我熟悉使用ExecuterService,但没有一种方法可以让批处理更新逻辑也在其中
我的整个应用程序代码如下所示:
while (null != (line = getNextLine())) {
Subscriber sub = getSub(line); // creates subscriber object by parsing the line
persistSub(sub); // JDBC - PreparedStatement insert query executed
}
需要知道一种方法,在这种方法中,我可以使用多个线程和批处理更新或任何可用于此类情况的现有框架或Java API更快地处理它
# 1 楼答案
persistSub(sub)
不应立即访问数据库。相反,它应该将sub
存储在长度为500-1000的数组中,并且只有当数组已满或输入文件终止时,才将其包装在Runnable
中并提交到线程池。然后Runnable
通过jdbc访问数据库,如JDBC Batching with PrepareStatement Object中所述更新
如果写入数据库的速度慢,而读取输入文件的速度快,则可以创建许多包含数据的数组,等待写入数据库,系统可能会耗尽内存。因此
persistSub(sub)
应该跟踪分配的数组的数量。最简单的方法是使用Semaphore初始化为允许数量的数组。在分配新数组之前,persistSub(sub)
会生成Semaphore.aquire()
。每个Runnable
任务在结束前都会生成Semaphore.release()