使用多线程并处理子线程异常数据的处理结果(非阻塞)

1.service利用线程池调用线程并处理子线程异常数据

@Slf4j
@Service
public class AutoQueryAccountCurrentDayBalanceService {
    private String url;
    private String port;
    private String requestPath;
    @Autowired
    private PathUrlConfig pathUrlConfig;
    @Autowired
    private BankAccountDao bankAccountDao;
    ThreadPoolExecutor pool = new ThreadPoolExecutor(10,10,60,
            TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>(10),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());
    public OrgResultDto queryCurrentBalance(List<BankAccountDto> list) {
        url=pathUrlConfig.getAccountBalancesHost();
        port=pathUrlConfig.getAccountBalancesPort();
        requestPath=pathUrlConfig.getQueryAccountCurrentDayBalanceRequestPath();
        OrgResultDto userResultDto=null;
        try {
            if (list == null||list.size() == 0) {
                log.info("传递参数对象为空");
                list=bankAccountDao.findAll();
            }
            log.info("共查询出"+list.size()+"个银行账户");
            List<Future<BankAccountDto>> errorList = new ArrayList<>();
            CountDownLatch tasks=new CountDownLatch(list.size());
            for (BankAccountDto bankAccountDto : list) {
                QueryAccountCurrentDayBalanceTaskThread theCallable = new QueryAccountCurrentDayBalanceTaskThread(bankAccountDto.getAccountno(),bankAccountDto.getSystemCode(),1,url,port,requestPath,bankAccountDto);
                Future<BankAccountDto> future = pool.submit(theCallable);
                tasks.countDown();
                errorList.add(future);
            }
            tasks.await();
            List<BankAccountDto> list1=new ArrayList<>();
            for(Future<BankAccountDto> future : errorList){
                if (future.get()!=null){
                    list1.add(future.get());
                }
            }
            if (list1.size() ==0){
                return new OrgResultDto(true, "200", "程序执行成功", null, null);
            }
            log.info("程序执行完毕,共有"+list1.size()+"条异常数据");
            log.info("开始处理异常数据");
            Long start=System.currentTimeMillis();
            while(list1.iterator().hasNext()){
                long temp=System.currentTimeMillis();
                if ((temp-start)/1000>60) {
                    return new OrgResultDto(false, "-1", "检测到异常数据"+list1.iterator().next().getAccountno(), null, list1);
                }
                Thread.sleep(100);
                BankAccountDto bankAccountDto=list1.iterator().next();
                QueryAccountCurrentDayBalanceTaskThread theCallable = new QueryAccountCurrentDayBalanceTaskThread( bankAccountDto.getAccountno(), bankAccountDto.getSystemCode(), 1, url, port, requestPath, bankAccountDto);
                Future<BankAccountDto> future = pool.submit(theCallable);
                if (future.get() == null) {
                    list1.remove(list1.iterator().next());
                }
            }
            long end=System.currentTimeMillis();
            long runTime=(end-start)/1000;
            log.info("异常数据处理完毕,用时"+runTime+"秒");
            userResultDto= new OrgResultDto(true, "200", "程序执行成功", null, null);
        }catch (InterruptedException e){
            Thread.currentThread().interrupt();
            e.printStackTrace();
            userResultDto= new OrgResultDto(false, "-1", "睡眠线程执行异常", null, null);
        } catch (Exception e){
            e.printStackTrace();
            userResultDto= new OrgResultDto(false, "-1", "程序执行异常", null, null);
        }
        return userResultDto;
    }
}

2.子线程处理(返回异常数据)

@Slf4j
public class QueryAccountCurrentDayBalanceTaskThread implements Callable<BankAccountDto> {

    private int operstionType;
    private String systemId;
    private String cAccountCode;
    private int currencyCode;
    private String systemCode;
    private String ID_URL;
    private String port;
    private String requestPath;
    private BankAccountDto bankAccountDto;
    public QueryAccountCurrentDayBalanceTaskThread(String cAccountCode,String systemCode,
                                                   int currencyCode,String ID_URL,String port,
                                                   String requestPath,BankAccountDto bankAccountDto){
        this.operstionType=10;
        this.systemId = "FC";
        this.cAccountCode = cAccountCode;
        this.currencyCode = currencyCode;
        this.ID_URL=ID_URL;
        this.port = port;
        this.requestPath = requestPath;
        this.systemCode=systemCode;
        this.bankAccountDto=bankAccountDto;
    }
    @Override
    public BankAccountDto call() throws Exception {
        log.info("进入银行当日余额线程");
        PreparedStatement preparedStatement = null;
        JConnection connection = null;
        ResultSet rs = null;
        try {
            JParamObject paramObject = JParamObject.getInstance();
            connection = DBUtils.getConnection(paramObject);
            log.info("调用银行账户当日余额:");
            GetRestTemplate getRestTemplate=new GetRestTemplate();
            RestTemplate restTemplate = getRestTemplate.instanceRestTemplate();
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
            Map<String, Object> headerMap = new HashMap<>();
            headerMap.put("language", "zh-cn");
            headerMap.put("sendTime", DateUtil.getDateStr() + " " + DateUtil.getTimeStr());
            Map<String, Object> queryInfoMap = new HashMap<>();
            queryInfoMap.put("OperationType",operstionType);
            queryInfoMap.put("SystemID",systemId);
            queryInfoMap.put("AccountCode",cAccountCode);
            queryInfoMap.put("CurrencyCode",currencyCode);
            List<Map<String, Object>> list = new ArrayList<>();
            list.add(queryInfoMap);
            Map<String, Object> map=new HashMap<>();
            map.put("header",headerMap);
            map.put("requestInfo",list);
            String str=JSONObject.toJSONString(map);
            log.info("封装的请求参数是:"+str);
            log.info("URL是:"+ID_URL +":" + port+ requestPath);
            //发送请求
            String resultString=restTemplate.postForObject(ID_URL +":" + port+ requestPath, str, String.class);
            log.info("线程调用查询账户当日余额接口,返回的数据是:"+resultString);
            ResAccountDto resAccountDto =  JSONObject.parseObject(resultString, ResAccountDto.class);
            if ("0000".equals(resAccountDto.getProcessCode())){
                for(ResAccountDetailInfoDto resAccountDetailInfoDto : resAccountDto.getReturnDetailInfos()){
                    resAccountDetailInfoDto.setDate(resAccountDetailInfoDto.getDate().replaceAll("-","").split(" ")[0]);
                    //根据日期和账号查询是否有该账户的余额
                    String sql = "select F_XTZH as xtzh from ZJ_ZHYE_JK where F_XTZH=? and F_DATE=?";
                    log.info("重试根据编号查询组织信息sql:" + sql);
                    preparedStatement = connection.prepareStatement(sql);
                    preparedStatement.setString(1, resAccountDetailInfoDto.getAccountCode());
                    preparedStatement.setString(2,resAccountDetailInfoDto.getDate());
                    rs = preparedStatement.executeQuery();
                    if (rs.next()){
                        //删除现有数据
                        String deleteSql = "delete from ZJ_ZHYE_JK where F_XTZH=? and F_DATE=?";
                        preparedStatement = connection.prepareStatement(deleteSql);
                        preparedStatement.setString(1, resAccountDetailInfoDto.getAccountCode());
                        preparedStatement.setString(2,resAccountDetailInfoDto.getDate());
                        if(preparedStatement.executeUpdate()>0){
                            log.info("删除"+resAccountDetailInfoDto.getAccountCode()+"在"+resAccountDetailInfoDto.getDate()+"日余额成功");
                        }
                    }
                    //添加数据
                    String insertSql = "insert into ZJ_ZHYE_JK(F_BZBH,F_DATE,F_KYYE,F_XTZH,F_TIME,F_SJLY) values(?,?,?,?,?,?)";
                    preparedStatement = connection.prepareStatement(insertSql);
                    preparedStatement.setInt(1, resAccountDetailInfoDto.getCurrencyCode());
                    preparedStatement.setString(2, resAccountDetailInfoDto.getDate());
                    preparedStatement.setDouble(3, resAccountDetailInfoDto.getBalance());
                    preparedStatement.setString(4, systemCode);
                    preparedStatement.setString(5,DateUtil.getDateStr()+" "+DateUtil.getTimeStr());
                    preparedStatement.setString(6,"1");
                    if(preparedStatement.executeUpdate()>0) {
                        log.info("添加" + resAccountDetailInfoDto.getAccountCode() + "在" + resAccountDetailInfoDto.getDate() + "日余额成功");
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("程序执行异常");
            return bankAccountDto;
        }finally {
            try{
                rs.close();
                preparedStatement.close();
                connection.close();
            }catch (Exception e){
                log.error("关闭链接异常");
            }
        }
        return null;
    }


}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值