日期:2014-05-20  浏览次数:20734 次

如何进行ExecutorService的内存管理?
问题是这样的:我有一大批的任务需要多线程处理,我使用了Executors.newFixedThreadPool()来创建线程池,并使用ExecutorService.submit()方法提交Callable对象用于执行,在Callable对象中存储了一些程序运行所需的对象。由于需要提交的任务数量太大,而且submit方法又是不阻塞的,很快就把内存空间用完了。

我想请问,ExecutorService是在什么时候释放Callable对象的空间的?是在Callable被执行完以后吗?我该如何进行内存的管理?我想控制提交任务的速率,比如当内存空间不足的时候就阻塞submit,直到一些任务被执行完以后释放出足够的空间。能做到吗?

------解决方案--------------------
哦,两个建议:
1、先用队列管理(比如数据库表)待执行任务,企图执行的任务数据先放入数据库中,这样避免一下子全把Callable对象都创建出来;用一个线程去检查ExecutorService的情况,有空闲了再从数据库中拿一条任务。
2、用一个通用的很小的Callable对象,待其被启动后再去初始化其执行任务所需各类数据和对象等。

如果能的话建议用第二种,简化自己的开发。
------解决方案--------------------
你所期望控制的资源,超出了ExecutorService的能力,它只能管理线程规模。

如果你一口气把整个文件的数据都变成Callable对象,相当于你把整个文件都已经装入内存了。

对于大规模数据处理而言,最好还是采用流式处理,所以你说的方案基本上也就是这样了。至于更为精确的规模控制,只能你自己来处理,也就是每次分配Callable的时候,就记录下它所处理数据量的规模;处理完毕的就扣除这个规模并通知主线程;然后你的主线程负责控制总体规模及读取下一个数据库并分配任务就行了。