In actual work, a business scenario needs to be solved:
An external query service needs to be called in the project to verify that some of the customer's submitted data meets the criteria.
The external service provider has a strong tendency to encapsulate the query service into three call services, and needs to rotate the training call status, as shown in the following figure:
.
Recently, I learned that FutureTask is just a tool to solve this business scenario. With the reconstruction of the code at hand, only part of the code after the reconstruction is posted here:
public class OldClientValidateTask implements Callable { Logger logger = LoggerFactory.getLogger(OldClientValidateTask.class); private volatile boolean cannotQuitJob = true; private boolean overtime = false; /** * Total wait timeout */ private int totalWaitMinutes = 65; /** *Interval time */ private int intvervalMinutes = 2; @Override public Object call() throws Exception { if (StringUtils.isBlank(oldAcctIds)) return null; OldClientValidateInvoker oldClientValidateInvoker = SpringContextHolder.getBean(OldClientValidateInvoker.class); //Send request to the first interface String sendQueryResult = oldClientValidateInvoker.sendQuery(period, oldAcctIds); if (StringUtils.isBlank(sendQueryResult)) { logger.error("Data format returned from Baidu old user verification interface is abnormal" + sendQueryResult); throw new ResultNotMatchException(ErrorCodeMessageBucket.ERROR_CODE_RESULT_NOT_MATCH); } //Resolve the requestId Map<String, String> resultMap = (HashMap<String, String>) JsonMapper.fromJsonString(sendQueryResult, HashMap.class); String requestId = resultMap.get("data"); if (requestId == null) return null; //Task start time final LocalDateTime startTime = LocalDateTime.now(); try { while (cannotQuitJob) { //No more calls if timeout if ((LocalDateTime.now().isAfter(startTime.plusMinutes(totalWaitMinutes)))) { overtime = true; logger.info("Overtime exit,Timeout time:" + totalWaitMinutes); break; } //Second interface boolean requestSucceed = oldClientValidateInvoker.checkStatus(requestId); logger.info("Whether the request call is successful: {}", requestSucceed); if (requestSucceed) { //Call the third interface to return real data return fetchResult(oldClientValidateInvoker, requestId); } //If not, wait if (cannotQuitJob) { Thread.sleep(1000 * 60 * intvervalMinutes); } } } catch (Exception e) { e.printStackTrace(); } return null; } }
The caller's procedure is as follows:
//Create asynchronous call task OldClientValidateTask oldClientValidateTask = new OldClientValidateTask(); FutureTask<List<Foo>> future = new FutureTask<List<Foo>>(oldClientValidateTask); // Create thread pool (using predefined configuration) ExecutorService executor = Executors.newCachedThreadPool(); executor.execute(future); //The query return result will wait here until the other party returns the query result, and asynchronous synchronization is realized. List<Foo> dbdSjClientRenewInfos = future.get();
This is a real scene. FutureTask is useful here.