固定个数的线程池,每个线程处理自己的任务
CountDownLatch countDownLatch = new CountDownLatch(maxThread);
来控制所有任务执行完成。
private static AtomicBoolean RUN_FLAG = new AtomicBoolean(false);
private String singleHandler(int pageSize, Integer maxThread) {
if (!RUN_FLAG.compareAndSet(false, true)) {
log.info("【余额退出】任务进行中,不能再次执行");
return "任务进行中,不能再次执行";
}
try {
this.handler(pageSize, maxThread);
return "处理完成";
} finally {
RUN_FLAG.set(false);
}
}
private void handler(int pageSize, Integer maxThread) {
if (maxThread == null) {
maxThread = 10;
}
final int maxThreads = maxThread;
CountDownLatch countDownLatch = new CountDownLatch(maxThread);
ExecutorService es = Executors.newFixedThreadPool(maxThread);
try {
for (int i = 0; i < maxThread; i++) {
final int mod = i;
try {
es.execute(() -> {
try {
log.info("【余额退出】开始处理,第{}个线程", mod);
this.subAccountExit(pageSize, maxThreads, mod, null);
log.info("【余额退出】处理完成,第{}个线程", mod);
} catch() {
log.error("【余额退出】子线程处理出现了异常,第{}个线程.", mod, e);
} finally {
countDownLatch.countDown();
}
});
} catch (Exception e) {
log.error("【余额退出】处理出现了异常,第{}个线程", mod, e);
}
}
try {
log.info("【余额退出】开始等待所有的线程执行");
countDownLatch.await();
log.info("【余额退出】所有线程执行完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
log.info("【余额退出】shutdown线程池,开始");
es.shutdown();
log.info("【余额退出】shutdown线程池,完成");
}
}
private void subAccountExit(Integer pageSize,
Integer maxThread,
Integer mod,
Long subAccountId) {
List<Integer> typeList = Arrays.asList(1, 2, 5, 10);
Long startId = 0L;
do {
log.info("【子账户余额退出】线程={},开始处理id>{}开始的数据", Thread.currentThread().getName(), startId);
List<FinancePlanSubAccount> subAccountList = subAccountDao.getSubAccountList(typeList,
startId, pageSize, maxThread, mod, subAccountId);
if (subAccountList.isEmpty()) {
return;
}
startId = subAccountList.get(subAccountList.size() - 1).getId();
for (FinancePlanSubAccount subAccount : subAccountList) {
try {
// todo 处理具体业务
} catch (Exception e) {
log.error("【子账户余额退出异常】id={}", subAccount.getId(), e);
}
}
} while (true);
}
<select id="getSubAccountList" resultType="com.caikee.core.model.FinancePlanSubAccount">
SELECT
<include refid="Base_Column_List" />
FROM
finance_plan_sub_account
WHERE
id > #{startId}
<if test="subAccountId != null">
and id = #{subAccountId}
</if>
<if test="maxThread != null and mod != null">
and mod(user_id, #{maxThread}) = #{mod}
</if>
and `exit` = 1
and `type` IN
<foreach item="item" collection="typeList" open="(" separator="," close=")">
#{item}
</foreach>
order by id asc
limit #{pageSize}
</select>
来源:oschina
链接:https://my.oschina.net/u/3777515/blog/3210694