首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多线程文件处理和数据库批量插入

多线程文件处理和数据库批量插入
EN

Stack Overflow用户
提问于 2016-06-15 00:42:43
回答 1查看 651关注 0票数 0

我有一个Java主应用程序,它将逐行读取文件。每一行代表订阅者数据。

代码语言:javascript
运行
复制
name, email, mobile, ...

为正在处理的每一行创建一个subscriber对象,然后使用JDBC将该对象持久化到数据库中。

PS:输入文件大约有1500万订户数据,应用程序大约需要10-12个小时来处理。我需要将这个时间减少到2-3个小时左右,因为这个任务是一个迁移活动,我们得到的停机时间大约是4-5个小时。

我知道我需要使用多线程/线程池可能是Java的原生ExecuterService。但我也被要求进行一次批量更新。假设有50或100个工作线程的线程池,批量更新500-1000个订阅者。

我熟悉使用ExecuterService,但没有一种方法可以在其中包含批处理更新逻辑。

我的整个应用程序代码如下所示:

代码语言:javascript
运行
复制
while (null != (line = getNextLine())) {
    Subscriber sub = getSub(line); // creates subscriber object by parsing the line
    persistSub(sub); // JDBC - PreparedStatement insert query executed
}

我需要知道一种方法,我可以更快地处理它与多线程和使用批量更新或任何现有的框架或Java API的,可以用于这种情况。

EN

回答 1

Stack Overflow用户

发布于 2016-06-15 06:24:43

persistSub(sub)不应立即访问数据库。相反,它应该将sub存储在长度为500-1000的数组中,并且仅当数组已满或输入文件终止时,才将其包装在Runnable中并提交到线程池。然后,就像JDBC Batching with PrepareStatement Object中描述的那样,Runnable通过jdbc访问数据库。

更新

如果写入数据库的速度较慢,而读取输入文件的速度较快,则可能会创建许多包含等待写入数据库的数据的数组,并且系统可能会耗尽内存。因此,persistSub(sub)应该跟踪已分配数组的数量。最简单的方法是使用允许的数组数量初始化的Semaphore。在分配新数组之前,persistSub(sub)会生成Semaphore.aquire()。每个Runnable任务在结束之前都会生成Semaphore.release()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37817746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档