大家一起来探讨一下一个多线程任务的设计吧,希望高手进来指教

TGITCIC
Java领域优质创作者
博客专家认证
2008-09-28 10:17:29
假设有N条记录要从数据库中读出,然后导成文件

我是想到了以下两个方法,但也有些疑问
一、固定的5个线程,每个线程处理100条记录

问题是:当这5个线程处理外500条记录后,怎么办?全部WAIT()在那边,然后当新的500条记录分配下来后一个个NOTIFY,那这5个线程如何让其再次运行?

重新NEW出来5个线程,那这样JVM不是来不及释放


二、线程池,线程池和JDBC连接池一样,开5个线程,然后每个线程处理100条记录,把N条记录一起扔给这个线程池,此线程池固定处理是500条记录,其他记录排队?

问题是: 排队?排在那边,也是排在内存中啊?那我有100万条记录,就是有100万-500条记录记录排在内存中啊?我用多线程处理就是希望想分批读出记录做处理,

这样一来不是起不到效果了?

请大家参与讨论
...全文
231 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
TGITCIC 2008-10-05
  • 打赏
  • 举报
回复
散分了,谢谢各位!
rabbit_zizhu 2008-09-29
  • 打赏
  • 举报
回复
先记下,有空来看
qiudawei115 2008-09-29
  • 打赏
  • 举报
回复
把数据量切开分批次取出来再处理,对每批次使用线程池,处理完再取
类似于分页,只是多分一些,减少下内存消耗

菜鸟看法
mjjzg 2008-09-28
  • 打赏
  • 举报
回复
不是很清楚,但你可以将它放入一个时间里,当执行500后将时间停止,当再用时将时间打开即可
wve 2008-09-28
  • 打赏
  • 举报
回复
用多线程,connection 池
holyboyzy 2008-09-28
  • 打赏
  • 举报
回复
不懂 楼主的意思 帮顶一下吧
fangsp 2008-09-28
  • 打赏
  • 举报
回复
帮顶一个
期待着高手的到来
liaoyi_ipanel 2008-09-28
  • 打赏
  • 举报
回复
帮顶
TGITCIC 2008-09-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 yeah920 的回复:]
帮忙顶一下,让了解的人来解答.
[/Quote]

按照您的意思就是,有任务来了就唤醒,是不就是说,如果我这个是一个导出数据成文件的程序,那这个进程的生命是随着我整个程序的开始而开始,结束而结束?

还有,您指的让它一直SLEEP是指WAIT()还是SLEEP(),如果是SLEEP(),如何弄醒它?
天涯海角 2008-09-28
  • 打赏
  • 举报
回复
线程池肯定要更好一些啊.
不一定要销毁线程啊,可以让它们Sleep直到有新的任务在唤醒它们啊.
ThinkingInJava110 2008-09-28
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 Mr_Von 的回复:]
不懂 帮顶!
[/Quote]
顶!顶!!顶!!!
無名VF 2008-09-28
  • 打赏
  • 举报
回复
不懂 帮顶!
liky5387 2008-09-28
  • 打赏
  • 举报
回复
你以上这个想法应该已经挺好了.
你担心的这个问题可以用System.gc();
而且最好用线程池.

TGITCIC 2008-09-28
  • 打赏
  • 举报
回复
我再添一把油,我现在想到这样的设计:

还是5个线程,每个处理100条,一共假设有100万条记录

这5个线程处理完了500条数据后,自动销毁!

然后外层一个循环,再创建5个线程!

为什么我一定要分批处理的道理就是为了每次试内存里的记录不要太多。

现在有个问题,这样的设计我做过

5个线程处理完后,自动销毁(每个线程处理完100条记录这个条件满足自动退出)

然后发觉还有数据,再创建5个线程

可是我发觉,在TOMAT里,刚开始5个线程开始运行时,从86变成了91,OK,5个线程在运行时,内存一直是91,这个没问题

然后问题来了,这5个线程结束了(我用程序是跟到了,确实5个线程结束了),再创建5个线程时,内存长到了96

这样一直下去我就担心内存是不是就一直上升,如果是1亿条记录,内存不就给耗完了?

因此我就觉得奇怪,前面5个线程结束时(满足线程运行条件结束,且所有的都关了),内存怎么没有施放?

是不是我这个设计还是有问题,请高人分析!
renmms 2008-09-28
  • 打赏
  • 举报
回复
关注。
乐快乐 2008-09-28
  • 打赏
  • 举报
回复
占个位子,关注。
cuixiuqin1954 2008-09-28
  • 打赏
  • 举报
回复
楼主好人我来绑定!!!
hulians4800 2008-09-28
  • 打赏
  • 举报
回复
可以考虑先把数据存入队列,N条数据来的时候就先把数据原模原样的存入数据库,然后可以建立一个创建定时器,在定制任务,比如每个10秒 处理100条数据。
比如
cycletime=10000;
//创建定时器
Sender.timer = new Timer(true);
//定制任务
Sender.timer.schedule(new TimerTask() {
public void run() {
new SenderThread().start();
}
}, 0, cycletime);
红色部分就是每个多少时间生成一个新的发送数据的线程,每次从队列数据库中取出100条数据进行处理,当然数据从队列出来的时候是要考虑线程安全的。
liang8305 2008-09-28
  • 打赏
  • 举报
回复
另外,你还要一个逻辑上的错误

既然你有100W条记录,分5个线程,为什么是每个线程分配100条,然后等这些线程处理完100条了再分100条?
直接每个线程分配100W/5条就可以了啊,

至于你说的有100W条在内存
记录在不在内存,取决你什么时候取出来,而不是取决于你什么时候去处理

如果你不想占内存,你就每次取少部分取来处理,就像分页一样
liang8305 2008-09-28
  • 打赏
  • 举报
回复
逻辑还是和数据库链接的使用一样的,要用生成,用完杀掉.......

一个处理类,继承自线程,里面有一个属性保存要处理的记录
启动后就运行你的记录处理逻辑,只处理获得的记录,处理完就完了,这个线程自动就会消失

一个主类,取记录,取够你想拆分的数量(100条)后,
就new一个处理类,把这100条记录传给他,让他start去处理
再取100条记录,再new一个处理类,再start

逻辑就应该是这样,至于说频繁生成线程销毁线程的开销,可以通过调节你的拆分数量来控制
另外,线程池也是为了优化这点而生的
但并不是说要保持住多少个线程让他wait在那里来处理,这不是一个好的业务逻辑

加载更多回复(2)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧