Java 多线程写文件

起因

朋友有一个大的文件,需要把里面的格式做转换后重新生成一个新的文件,然后用matlab做一些数据处理,但是说做这个数据格式转换的时候过程十分慢,而且跑了好几个小时都没搞好,我一看文件大小300m,就自信满满的说我来帮你搞定。

过程

拿到文件之后格式是这样的

image

我看了一下这个数据大概将近5百万条,都需要转换成这种格式

image

我以为数据大小没有关系,就直接跑了一个单线程做所有的事情,一行一行读出来,转成对象后,然后把对象一个一个拿出来,转成最后的格式输出。

开始跑了之后,发现跑了好久都没有出来,打了个断点,发现跑了十几分钟后跑了一半的数据,心有不甘啊,太慢了。然后开始修改代码

既然太慢了,搞多线程干

直接把转换的过程封装到方法里面,新建了一个线程池

private ThreadPoolExecutor executor = new ThreadPoolExecutor(20,30,60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(2000),new ThreadPoolExecutor.CallerRunsPolicy());

重新开始跑,发现跑到一半任务左右又变得很慢

思考

  • 队列被塞满了,因为我的拒绝策略是CallerRunsPolicy
  • 5百万数据的话,是不是一下子就把队列给塞满了
  • 应该任务的处理时间内提交可以处理完成的任务数量

所以又改了一下

  1. 把阻塞队列容量加大到20000
  2. 提交任务的时候每30个任务主线程sleep(200),减慢任务提交速度

改完之后跑还是同样的问题,比较疑惑,打开资源管理器观察,内存占用%80,cpu占用100%

思考

  • 内存还有剩余,cpu100%,说明有线程一直占用着cpu,但是为什么还是很慢的速度呢,看来不是工作线程占用这cpu,(其实这个时候应该想到的是垃圾回收线程占用cpu)
  • 关闭程序之后内存直接降到了40%
  • 可能是堆内存不够了,导致一直fullGC,一直没有多余的内存空间去分配新的空间创建新的对象,所以导致很慢

基于上面的思考做了改进

  • 吧idea的vm运行时参数改了一下,改成-Xmx2048m -Xms2048m,全部改成了两个G,

跑了一下发现还是同样的问题,虽然进度稍微多了一点,可以感觉到是堆内存的问题了,接下来的改进也就可以知道了,不能把全部的数据读取之后转为对象之后在进行转换,这样会造成堆空间不足,无法分配空间。改进:每50个异步任务进行一次阻塞,并将结果直接做转换后写入新的文件。修改之后整个过程耗时1分钟左右吧。

学习

这次的数据转换过程,其实一些理论自己都懂,但是没有运用到实际的写代码的过程,这次稍微有一点体会了。

  • 多线程工作,数据量大的时候,不应该全部阻塞去等待结果,这样子会占用很多的内存空间
  • 前面的思考其实有很多是错误的方向,就算任务塞满了,和你的处理工作是不相关的,因为拒绝策略是CallerRunsPolicy(),所以线程池的队列大小没有关系
  • cpu占用100%的时候就应该想到去用Java提供的工具去看什么线程在占用cpu,因为任务一直被阻塞,所以肯定不是工作线程被阻塞了,肯定是垃圾回收线程在工作,jstat 看一下GC情况。
  • 内存占用很多的时候,jstat 看一下jvm的内存空间情况。这时候修改vm的xms和xmx是没有用的,就像线上频繁gc的时候用加机器的方法来解决问题,不是最终解决方法
  • 这种任务量很多的时候要考虑修改程序逻辑使一些对象可以及时释放,这样不会占用太多空间导致频繁full gc,降低cpu使用率
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容