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;
}
}