序言
最近需要做一个db to db的东西,总数据量三千万左右,我们需要将一个或者多个库中的表导出为Sql或者将一个或者多个sql文件导入到任意库。在这个过程中,我使用了多线程。(Python效率一言难尽)。那是必须要使用线程池的,但是执行一个sql文件或者导出如果耗时巨多,然后我们表又很多,会造成前面任务执行不完,后面任务有丢失的情况,所以我新定了一个策略,阻塞策略。意思就是如果有new Task ,那么线程池会等着处理完现在的任务再去处理他,再这过程中,不会有任务丢失。但是生产所带来的内存开销和资源交互开销是无法释放的(后面再谈解决方案)。
解决
重写RejectedExecutionHandler拒绝策略,代码如下:
/**
* block the queue when it is full
* @author Herche Jane
*/
public class BlockExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结束语
虽然这个策略暂时缓和了燃眉之急,但是似乎引发了内存问题(待解决和寻找根源)。请谨慎使用!