项目描述:定时任务扫描300万条数据库记录,并对每条记录执行检查操作(调用其他服务接口,发送短信等)。
版本迭代记录:
1)第一版:一次查询全部300万条数据放在JVM内存中,没有使用线程池,使用固定20个线程,每个线程循环不停的从内存中取一条数据执行,直到所有数据全部执行完为止。
这种方式耗时大约3个半小时,代码如下:
// 实现runnable接口的线程,infos:全部300条任务 CheckTask checkTask = new CheckTask(infos); // 固定20个线程执行,线程不能回收再利用(线程池可以) for (int i = 0; i < 20; i++) { Thread t = new Thread(checkTask, name + "_" + i); t.start(); } private class CheckTask implements Runnable { private List<Info> infos; private volatile int count = 0; public CheckTask(List<Info> infos) { this.infos= infos; } @Override public void run() { boolean done = false; while (!done) { try { Info info = null; // 使用同步锁 synchronized (infos) { if (count < infos.size()) { info = infos.get(count); count++; } else { done = true; break; } } if (info != null) { // 对取到的一个任务执行业务逻辑 ... } } catch (Exception e) { // 异常处理 } } // while } }
2)第二版:使用线程池,线程池核心线程数为1,最大线程数为50,等待队列为100。每次执行1000条任务
3)第三版: