多线程实战2

女生的网名这么多〃 提交于 2020-03-25 11:45:47

3 月,跳不动了?>>>

固定个数的线程池,每个线程处理自己的任务

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>

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!