多线程执行job任务 线程池

先占个坑,后面补齐


本文主要介绍我们项目在晚上定时执行 job 的时候,由于数据量多,为缩短 job 的执行时间,采用线程池,多线程执行 job 的情况。


先看 job 任务的代码,我只保留了主要的:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 资产登记表数据同步
 * 
 * @author liusn19096
 */
@Service
public class FsAccountDiagJob {

    /**
     * 线程数量
     */
    private static final int EXENUMS = 20;

    /**
     * 每次查询的条数
     */
    private static final int ROWNUM = 500;

    /**
     * 线程池.
     */
    private ExecutorService exec;

    /**
     * 定义线程池
     */
    public FsAccountDiagJob() {
        exec = Executors.newFixedThreadPool(EXENUMS);
    }
 
    /**
     * job内容
     */
    private void doTaskContent(String fund_account, String money_type,
            String init_date) {
        if (exec == null) {
            exec = Executors.newFixedThreadPool(EXENUMS);
        }

        // 查询条件
        Map<String, Object> param = new HashMap<>();
        // 一次查询多少条
        param.put("rownum", ROWNUM);
        // 未处理
        param.put("rzdeal_flag", RZDEAL_FLAG);
        // 默认计算周期为9
        param.put("calculate_cycle", ConstantUtil.DEFAULT_CALCULATE_CYCLE);
        // 将参数 资金账户&币种类别 放入查询参数
        this.putParamToMap(fund_account, money_type, init_date, param);

        // 循环查询
        while (true) {
            // 查询资产登记表,使用param
            List<AssetAndCalculate> list = fsAcctAssetDao
                    .queryAssetAndCalculate(param);
            // 非空
            if (!CollectionUtils.isEmpty(list)) {
                try {
                    // 处理数据并更新rzdeal_flag=1
                    this.dealAssetAndUpdate(list);
                } catch (Exception ex) {
                    LOGGER.error("FsAccountDiagJob.doJob dealAssetAndUpdate",
                            ex);
                }
            }
            // 最后一次查询或者为空,跳出循环
            if (CollectionUtils.isEmpty(list) || list.size() < ROWNUM) {
                break;
            }

        }
        LOGGER.info("FsAccountDiagJob end");

    }

    /**
     * 处理数据并更新处理标志
     * 
     * @param list
     */
    private void dealAssetAndUpdate(List<AssetAndCalculate> list) {

        LOGGER.info("dealAssetAndUpdate START");
        List<Future<AccountDiagData>> threadRlt = new ArrayList<>();
        List<FsDayRankings> dayRankList = new ArrayList<>();
        List<FsStockhold> stockholdList = new ArrayList<>();
        List<FsCalculateResult> resultList = new ArrayList<>();
        List<FsAcctAsset> assetList = new ArrayList<>();
        List<FsCalculateResultDay> resultDayList = new ArrayList<>();
        // 循环处理
        for (AssetAndCalculate assetAndCalculate : list) {
            threadRlt.add(exec.submit(new FsAccountDiagThread(assetAndCalculate,
                    fsDataStockDao, initasset, fsCsiLogic, fsCalculateResultDao,
                    fsDeliverDao, fsAcctAssetDao, fsDayRankingsDao)));
        }
        // 各线程处理结果汇总,保证所有线程执行完之后才能继续下面的代码
        for (Future<AccountDiagData> f : threadRlt) {
            try {
                AccountDiagData data = f.get();
                if (data != null) {
                    if (data.getSuccess()) {
                        if (data.getAsset() != null) {
                            assetList.add(data.getAsset());
                        }
                        if (data.getDayRank() != null) {
                            dayRankList.add(data.getDayRank());
                        }
                        if (data.getResult() != null) {
                            resultList.add(data.getResult());
                        }
                        if (data.getResultDay() != null) {
                            resultDayList.add(data.getResultDay());
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.error(e.getLocalizedMessage(), e);
            }
        }
        // 处理成功的数据入库
        fsAccountDiagService.saveAccountDiagData(dayRankList, stockholdList,
                resultList, assetList, resultDayList);
        LOGGER.info("dealAssetAndUpdate END");
    }

}


下面看看对应线程 FsAccountDiagThread 类的代码,只保留了主要的:

import java.util.concurrent.Callable;

public class FsAccountDiagThread implements Callable<AccountDiagData> {

    /**
     * logger.
     */
    private static final Logger LOGGER = LoggerFactory
            .getLogger(FsAccountDiagThread.class);

    private final FsDataStockDao fsDataStockDao;

    private final BigDecimal initAsset;

    private final IFsCsiLogic fsCsiLogic;

    private final FsCalculateResultDao fsCalculateResultDao;

    private final FsDeliverDao fsDeliverDao;

    private final FsAcctAssetDao fsAcctAssetDao;

    private final AssetAndCalculate assetAndCalculate;

    private final FsDayRankingsDao fsDayRankingsDao;

    @Autowired
    public FsAccountDiagThread(AssetAndCalculate assetAndCalculate,
            FsDataStockDao fsDataStockDao, BigDecimal initAsset,
            IFsCsiLogic fsCsiLogic, FsCalculateResultDao fsCalculateResultDao,
            FsDeliverDao fsDeliverDao, FsAcctAssetDao fsAcctAssetDao,
            FsDayRankingsDao fsDayRankingsDao) {
				// 将dao等service赋值Dao线程
        this.assetAndCalculate = assetAndCalculate;
        this.fsDataStockDao = fsDataStockDao;
        this.initAsset = initAsset;
        this.fsCsiLogic = fsCsiLogic;
        this.fsCalculateResultDao = fsCalculateResultDao;
        this.fsDeliverDao = fsDeliverDao;
        this.fsAcctAssetDao = fsAcctAssetDao;
        this.fsDayRankingsDao = fsDayRankingsDao;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.util.concurrent.Callable#call()
     */
    @Override
    public AccountDiagData call() throws Exception {
        AccountDiagData data = new AccountDiagData();
        // 进行数据的计算,返回结果data
        return data;
    }
    
}



扫描二维码关注公众号,回复: 1900995 查看本文章










































猜你喜欢

转载自blog.csdn.net/u010343544/article/details/78280276