Преглед изворни кода

多线程任务优化: 如果所有任务都正常时 latch 会一直不为0,使用原子类记录执行的任务数,判断任务数是否为最大值,最大值说明执行完了,就调用condown

xiari пре 10 месеци
родитељ
комит
affffaf783

+ 79 - 32
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/CardConsumeValidation.java

@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -43,7 +44,9 @@ public class CardConsumeValidation {
     private static final Map<String, String> MEAL_TYPE_NAMES = ConsumeConstants.mealNameMap;
     private final CommonCheck commonCheck;
     private final ValidationParam validationParam;
-    private final ThreadPoolTaskExecutor taskExecutor;
+    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
+    // 异步线程的任务个数
+    private static final int THREAD_TASK = 2;
 
     public R<ErrorInfo> cardValidation(ConsumptionBo bo, XfTermVo termVo, RemoteCardVo userCardVo,
                                        RemoteMealTypeVo mealTypeVo,
@@ -71,23 +74,25 @@ public class CardConsumeValidation {
     private R<ErrorInfo> executeCardValidationChain(CardConsumeValidationContext ctx) {
         // 创建CountDownLatch 有1个任务返回错误时就唤醒主线程
         CountDownLatch latch = new CountDownLatch(1);
+        // 任务执行完也要唤醒主线程
+        AtomicInteger completeCount = new AtomicInteger();
         // 存储第一个错误结果
         AtomicReference<R<ErrorInfo>> firstError = new AtomicReference<>(null);
         // 创建验证任务列表
-        List<Callable<R<ErrorInfo>>> validationTasks = getCardValidCallables(ctx, firstError, latch);
+        List<Callable<R<ErrorInfo>>> validationTasks = getCardValidCallables(ctx, firstError, latch,completeCount);
         // 所有任务的结果集合
         List<Future<R<ErrorInfo>>> futures = new ArrayList<>();
         // 提交所有验证任务
         for (Callable<R<ErrorInfo>> task : validationTasks) {
-            futures.add(taskExecutor.submit(task));
+            futures.add(threadPoolTaskExecutor.submit(task));
         }
 
         long starTime = System.currentTimeMillis();
         // 最终执行的结果,true 为正常执行结束及latch减至了0;false 为超时
         boolean finallyResult;
         try {
-            // 阻塞主线程,等待执行结果; latch 为0时,会唤醒主线程,最多阻塞10s
-            finallyResult = latch.await(10, TimeUnit.SECONDS);
+            // 阻塞主线程,等待执行结果; latch 为0时,会唤醒主线程,最多阻塞5s
+            finallyResult = latch.await(5, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             log.error("executeCardValidationChain- main 被中断 :{}", e.getMessage());
             Thread.currentThread().interrupt();
@@ -99,7 +104,7 @@ public class CardConsumeValidation {
         // 循环取消所有任务
         futures.forEach(f -> f.cancel(true));
         if (!finallyResult) {
-            log.error("executeCardValidationChain- 折扣和限次校验10s超时");
+            log.error("executeCardValidationChain- 折扣和限次校验5s超时");
             return commonCheck.createError(TradeStatusEnum.SysError);
         }
 
@@ -226,40 +231,82 @@ public class CardConsumeValidation {
      * @return
      */
     private List<Callable<R<ErrorInfo>>> getCardValidCallables(CardConsumeValidationContext ctx,
-                                                               AtomicReference<R<ErrorInfo>> firstError, CountDownLatch latch) {
+                                                               AtomicReference<R<ErrorInfo>> firstError,
+                                                               CountDownLatch latch,AtomicInteger completeCount) {
         List<Callable<R<ErrorInfo>>> validationTasks = new ArrayList<>();
         // 添加折扣验证任务
-        validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                // 已经有错误了,直接返回
-                return null;
+        validationTasks.add(() -> obtainCardValidTask(ctx, firstError, latch, completeCount));
+        validationTasks.add(() -> obtainCardLimitTask(ctx, firstError, latch, completeCount));
+        return validationTasks;
+    }
+
+    /***
+     * 获取卡片限次验证验证任务
+     *
+     * @param ctx
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainCardLimitTask(CardConsumeValidationContext ctx, AtomicReference<R<ErrorInfo>> firstError,
+                                             CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        // 已经有错误了,直接返回
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            //执行具体的校验逻辑
-            R<ErrorInfo> infoR = dealCardDiscount(ctx);
-            if (infoR != null && R.isError(infoR)) {
-                // 设置错误结果
-                firstError.set(infoR);
+            return null;
+        }
+        //执行具体的校验逻辑 卡片限次验证
+        R<ErrorInfo> infoR = dealCardLimited(ctx);
+        if (infoR != null && R.isError(infoR)) {
+            // 存储错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                // 已经有错误了,直接返回
-                return null;
+        }
+        return infoR;
+    }
+
+    /**
+     * 获取卡折扣验证任务
+     * @param ctx
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainCardValidTask(CardConsumeValidationContext ctx, AtomicReference<R<ErrorInfo>> firstError,
+                                             CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        // 已经有错误了,直接返回
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            //执行具体的校验逻辑 卡片限次验证
-            R<ErrorInfo> infoR = dealCardLimited(ctx);
-            if (infoR != null && R.isError(infoR)) {
-                // 存储错误结果
-                firstError.set(infoR);
+            return null;
+        }
+        //执行具体的校验逻辑
+        R<ErrorInfo> infoR = dealCardDiscount(ctx);
+        if (infoR != null && R.isError(infoR)) {
+            // 设置错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        return validationTasks;
+        }
+        return infoR;
     }
 
     private String getTaskName(int taskIndex) {

+ 107 - 47
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/CommonCheck.java

@@ -18,13 +18,11 @@ import org.dromara.common.core.domain.model.ErrorInfo;
 import org.dromara.common.core.enums.CardStatusEnum;
 import org.dromara.common.core.enums.TradeStatusEnum;
 import org.dromara.common.core.enums.UserAccountStatusEnum;
-import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.server.common.constant.ConsumeConstants;
 import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
 import org.dromara.server.common.util.CardDateUtils;
 import org.dromara.server.consume.business.*;
-import org.dromara.server.consume.cache.CardCacheManager;
 import org.dromara.server.consume.domain.vo.XfCardLimitedVo;
 import org.dromara.server.consume.domain.vo.XfTermVo;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -32,14 +30,12 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.text.MessageFormat;
-import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Supplier;
 
 /**
  * 消费业务通用验证类
@@ -56,11 +52,13 @@ import java.util.function.Supplier;
 public class CommonCheck {
     // 异步线程执行超时时间,以毫秒为单位
     private static final long VALIDATION_TIMEOUT = 500;
+    // 异步线程的任务个数
+    private static final int THREAD_TASK = 3;
 
     private final BaseBusiness baseBusiness;
     private final EmployeeBusiness employeeBusiness;
     private final CardBusiness cardBusiness;
-    private final ThreadPoolTaskExecutor taskExecutor;
+    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
     private final TermBusiness termBusiness;
 
     //region 账户、卡片与设备验证
@@ -89,24 +87,26 @@ public class CommonCheck {
     private R<ErrorInfo> executeTermValidationChain(AllowConsumeValidationContext ctx) {
         // 创建CountDownLatch 有1个任务返回错误时就唤醒主线程 // 使用CountDownLatch跟踪任务完成
         CountDownLatch latch = new CountDownLatch(1);
+        // 任务执行完也要唤醒主线程
+        AtomicInteger completeCount = new AtomicInteger();
         // 用于存储第一个错误结果
         AtomicReference<R<ErrorInfo>> firstError = new AtomicReference<>(null);
         // 创建验证任务列表
-        List<Callable<R<ErrorInfo>>> validationTasks = getTermValidCallables(ctx, firstError, latch);
+        List<Callable<R<ErrorInfo>>> validationTasks = getTermValidCallables(ctx, firstError, latch , completeCount);
 
         // 所有任务的结果集合
         List<Future<R<ErrorInfo>>> futures = new ArrayList<>();
         // 提交所有任务
         for (Callable<R<ErrorInfo>> task : validationTasks) {
-            futures.add(taskExecutor.submit(task));
+            futures.add(threadPoolTaskExecutor.submit(task));
         }
 
         long starTime = System.currentTimeMillis();
         // 最终执行的结果,true 为正常执行结束及latch减至了0;false 为超时
         boolean finallyResult;
         try {
-            // 阻塞主线程,等待执行结果; latch 为0时,会唤醒主线程,最多阻塞10s
-            finallyResult = latch.await(10, TimeUnit.SECONDS);
+            // 阻塞主线程,等待执行结果; latch 为0时,会唤醒主线程,最多阻塞5s
+            finallyResult = latch.await(5, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             log.error("executeTermValidationChain- main 被中断 :{}", e.getMessage());
             Thread.currentThread().interrupt();
@@ -118,7 +118,7 @@ public class CommonCheck {
         // 循环取消所有任务
         futures.forEach(f -> f.cancel(true));
         if (!finallyResult) {
-            log.error("executeTermValidationChain- 设备、账户、参数校验10s超时");
+            log.error("executeTermValidationChain- 设备、账户、参数校验5s超时");
             return createError(TradeStatusEnum.SysError);
         }
 
@@ -218,52 +218,112 @@ public class CommonCheck {
      * @return
      */
     private List<Callable<R<ErrorInfo>>> getTermValidCallables(AllowConsumeValidationContext ctx,
-                                                               AtomicReference<R<ErrorInfo>> firstError, CountDownLatch latch) {
+                                                               AtomicReference<R<ErrorInfo>> firstError,
+                                                               CountDownLatch latch,AtomicInteger completeCount) {
         List<Callable<R<ErrorInfo>>> validationTasks = new ArrayList<>();
 
         // 校验参数任务
-        validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
+        validationTasks.add(() -> obtainParamTask(ctx, firstError, latch, completeCount));
+        //消费设备校验
+        validationTasks.add(() -> obtainTermVTask(ctx, firstError, latch, completeCount));
+        //用户账户校验
+        validationTasks.add(() -> obtainUserTask(ctx, firstError, latch, completeCount));
+        return validationTasks;
+    }
+
+    /**
+     * 获取用户信息校验任务
+     * @param ctx
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainUserTask(AllowConsumeValidationContext ctx, AtomicReference<R<ErrorInfo>> firstError, CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            R<ErrorInfo> infoR = checkParam(ctx);
-            if (infoR != null && R.isError(infoR)) {
-                // 设置错误结果
-                firstError.set(infoR);
+            return null;
+        }
+        R<ErrorInfo> infoR = checkUserAccount(ctx);
+        if (infoR != null && R.isError(infoR)) {
+            // 存储错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        //消费设备校验
-        validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
+        }
+        return infoR;
+    }
+
+    /**
+     * 获取设备校验任务
+     * @param ctx
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainTermVTask(AllowConsumeValidationContext ctx, AtomicReference<R<ErrorInfo>> firstError,
+                                         CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            R<ErrorInfo> infoR = checkTerm(ctx);
-            if (infoR != null && R.isError(infoR)) {
-                // 存储错误结果
-                firstError.set(infoR);
+            return null;
+        }
+        R<ErrorInfo> infoR = checkTerm(ctx);
+        if (infoR != null && R.isError(infoR)) {
+            // 存储错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        //用户账户校验
-        validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
+        }
+        return infoR;
+    }
+
+    /**
+     * 获取参数校验任务
+     * @param ctx
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainParamTask(AllowConsumeValidationContext ctx, AtomicReference<R<ErrorInfo>> firstError,
+                                         CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            R<ErrorInfo> infoR = checkUserAccount(ctx);
-            if (infoR != null && R.isError(infoR)) {
-                // 存储错误结果
-                firstError.set(infoR);
+            return null;
+        }
+        R<ErrorInfo> infoR = checkParam(ctx);
+        if (infoR != null && R.isError(infoR)) {
+            // 设置错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        return validationTasks;
+        }
+        return infoR;
     }
 
     private String getTaskName(int taskIndex) {
@@ -679,9 +739,9 @@ public class CommonCheck {
 
         // if (ObjectUtil.equals(currentDateStr, consumeDateStr)) {
         // 重置卡天当日消费数据
-        taskExecutor.execute(() -> baseBusiness.resetCardConsumeInfo(userCardVo, mealType, consumeMoney, consumeDate));
+        threadPoolTaskExecutor.execute(() -> baseBusiness.resetCardConsumeInfo(userCardVo, mealType, consumeMoney, consumeDate));
         // 重置卡片当日限制数据
-        taskExecutor.execute(() -> baseBusiness.restCardLimitedInfo(mapCardLimited, cardLimitedVo, consumeMoney));
+        threadPoolTaskExecutor.execute(() -> baseBusiness.restCardLimitedInfo(mapCardLimited, cardLimitedVo, consumeMoney));
         // 重置人员当日总卡余
         // taskExecutor.submit(() -> baseBusiness.resetUserBalance(userId, balance));
         // }

+ 176 - 52
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/ConsumeRequestCheck.java

@@ -35,6 +35,7 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
 
@@ -51,6 +52,8 @@ import java.util.function.Supplier;
 @Service
 @RequiredArgsConstructor
 public class ConsumeRequestCheck {
+    private static final int THREAD_TASK = 6;
+
     private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
     private final CommonCheck commonCheck;
     private final CardConsumeValidation cardConsumevalidation;
@@ -283,10 +286,12 @@ public class ConsumeRequestCheck {
         long startTime = System.currentTimeMillis();
         // 创建CountDownLatch 有1个任务返回错误时就唤醒主线程 // 使用CountDownLatch跟踪任务完成
         CountDownLatch latch = new CountDownLatch(1);
+        // 任务执行完也要唤醒主线程
+        AtomicInteger completeCount = new AtomicInteger();
         // 用于存储第一个错误结果
         AtomicReference<R<ErrorInfo>> firstError = new AtomicReference<>(null);
         // 创建验证任务列表
-        List<Callable<R<ErrorInfo>>> validationTasks = getTermValidationCallables(context, firstError, latch);
+        List<Callable<R<ErrorInfo>>> validationTasks = getTermValidationCallables(context, firstError, latch,completeCount);
 
         // 所有任务的结果
         List<Future<R<ErrorInfo>>> futures = new ArrayList<>();
@@ -424,89 +429,208 @@ public class ConsumeRequestCheck {
      * @return
      */
     private List<Callable<R<ErrorInfo>>> getTermValidationCallables(TermConsumeValidationContext context,
-                                                                    AtomicReference<R<ErrorInfo>> firstError, CountDownLatch latch) {
+                                                                    AtomicReference<R<ErrorInfo>> firstError,
+                                                                    CountDownLatch latch,AtomicInteger completeCount) {
         List<Callable<R<ErrorInfo>>> validationTasks = new ArrayList<>();
 
         // 消费时间间隔验证
         validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
-            }
-            R<ErrorInfo> infoR = validateSwipeInterval(context);
-            if (infoR != null && R.isError(infoR)) {
-                // 设置错误结果
-                firstError.set(infoR);
-                latch.countDown();
-            }
-            return infoR;
+            return obtainTimeVTask(context, firstError, latch, completeCount);
         });
         // 单次消费限额判断
         validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
-            }
-            R<ErrorInfo> infoR = validateSingleLimit(context);
-            if (infoR != null && R.isError(infoR)) {
-                firstError.set(infoR);
-                latch.countDown();
-            }
-            return infoR;
+            return obtainMoneyTask(context, firstError, latch, completeCount);
         });
         // 卡有效期验证
         validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
-            }
-            R<ErrorInfo> infoR = validateCardValidity(context);
-            if (infoR != null && R.isError(infoR)) {
-                firstError.set(infoR);
-                latch.countDown();
-            }
-            return infoR;
+            return obtainCardTimeTask(context, firstError, latch, completeCount);
         });
         // 卡类型验证
         validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
-            }
-            R<ErrorInfo> infoR = validateCardType(context);
-            if (infoR != null && R.isError(infoR)) {
-                firstError.set(infoR);
-                latch.countDown();
-            }
-            return infoR;
+            return obtainCradTypeTask(context, firstError, latch, completeCount);
         });
         // 餐次验证
         validationTasks.add(() -> {
             R<ErrorInfo> errorInfoR = firstError.get();
             if (errorInfoR != null && R.isError(errorInfoR)) {
+                // 任务都结束了
+                if (completeCount.incrementAndGet() == THREAD_TASK) {
+                    latch.countDown();
+                }
                 return null;
             }
             R<ErrorInfo> infoR = validateMealLimit(context);
             if (infoR != null && R.isError(infoR)) {
                 firstError.set(infoR);
                 latch.countDown();
+            }else{
+                // 任务都结束了
+                if (completeCount.incrementAndGet() == THREAD_TASK) {
+                    latch.countDown();
+                }
             }
             return infoR;
         });
         // 日限额验证
         validationTasks.add(() -> {
-            R<ErrorInfo> errorInfoR = firstError.get();
-            if (errorInfoR != null && R.isError(errorInfoR)) {
-                return null;
+            return obtainDayLimitTask(context, firstError, latch, completeCount);
+        });
+        return validationTasks;
+    }
+
+    /**
+     * 获取日限额验证任务
+     * @param context
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainDayLimitTask(TermConsumeValidationContext context, AtomicReference<R<ErrorInfo>> firstError, CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
             }
-            R<ErrorInfo> infoR = validateDailyLimit(context);
-            if (infoR != null && R.isError(infoR)) {
-                firstError.set(infoR);
+            return null;
+        }
+        R<ErrorInfo> infoR = validateDailyLimit(context);
+        if (infoR != null && R.isError(infoR)) {
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
                 latch.countDown();
             }
-            return infoR;
-        });
-        return validationTasks;
+        }
+        return infoR;
+    }
+
+    /**
+     * 获取卡类验证任务
+     * @param context
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainCradTypeTask(TermConsumeValidationContext context, AtomicReference<R<ErrorInfo>> firstError,
+                                            CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+            return null;
+        }
+        R<ErrorInfo> infoR = validateCardType(context);
+        if (infoR != null && R.isError(infoR)) {
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+        }
+        return infoR;
+    }
+
+    /**
+     * 创建卡片信息校验任务
+     * @param context
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainCardTimeTask(TermConsumeValidationContext context, AtomicReference<R<ErrorInfo>> firstError,
+                                            CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+            return null;
+        }
+        R<ErrorInfo> infoR = validateCardValidity(context);
+        if (infoR != null && R.isError(infoR)) {
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+        }
+        return infoR;
+    }
+
+    /**
+     * 创建校验消费金额任务
+     * @param context
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainMoneyTask(TermConsumeValidationContext context, AtomicReference<R<ErrorInfo>> firstError,
+                                         CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+            return null;
+        }
+        R<ErrorInfo> infoR = validateSingleLimit(context);
+        if (infoR != null && R.isError(infoR)) {
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+        }
+        return infoR;
+    }
+
+    /**
+     * 创建消费时间间隔校验任务
+     * @param context
+     * @param firstError
+     * @param latch
+     * @param completeCount
+     * @return
+     */
+    private R<ErrorInfo> obtainTimeVTask(TermConsumeValidationContext context, AtomicReference<R<ErrorInfo>> firstError,
+                                         CountDownLatch latch, AtomicInteger completeCount) {
+        R<ErrorInfo> errorInfoR = firstError.get();
+        if (errorInfoR != null && R.isError(errorInfoR)) {
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+            return null;
+        }
+        R<ErrorInfo> infoR = validateSwipeInterval(context);
+        if (infoR != null && R.isError(infoR)) {
+            // 设置错误结果
+            firstError.set(infoR);
+            latch.countDown();
+        }else{
+            // 任务都结束了
+            if (completeCount.incrementAndGet() == THREAD_TASK) {
+                latch.countDown();
+            }
+        }
+        return infoR;
     }
 
     //validationTasks.add(() -> validateSwipeInterval(context));