ExecutorCompletionServiceを使用して、LinkedBlockingQueueはスレッドプールを管理してタスクを処理し、2つのタイプの結果値を返します.

8328 ワード

ExecutorCompletionServiceを使用して、LinkedBlockingQueueはスレッドプールを管理してタスクを処理し、2つのタイプの結果値を返します.
スレッドプールを日常的に使用する場合、スレッド処理結果を得る必要がある場合がよくあります.次に、特定のユーザー情報を追加し、検証した特定のインスタンスを使用して、対応する使用シーンを説明します.
1.メソッドが返す2つの結果タイプ
import java.io.Serializable;
/**
 *        ,                
 */
public class TwoTupleimplements Serializable {
public  A first;
public  B second;
public TwoTuple(A a, B b) {
this.first = a;
this.second = b;
}
public TwoTuple() {
}
@Override
public String toString() {
return "TwoTuple{" +
"first=" + first +
", second=" + second +
'}';
}
}

1.Controllerレイヤの対応する受信フロントエンドパラメータMapのセット.
 /**
     * showdoc
     *
     * @param channelCorpTemp    Map          
     * @return {"code":200,"message":"    ","data":{"..":"..."}}
     * @catalog   /provider
     * @title          
     * @description          
     * @method POST
     * @url http://ip:port/ylw/qhChannelCorp/api/addCorp
     * @number 99
     */
    @ResponseBody
    @RequestMapping(value = "addChannel", method = RequestMethod.POST)
    public ResultMessage addChannel(@RequestBody Map channelCorpTemp) {
        try {
            return qhChannelCorpService.addChannel(channelCorpTemp);
        } catch (Exception e) {
            logger.error(e.toString());
            return new ResultMessage(SysCode.FAILUE.getCode(), e.toString());
        }
    }


2.サービス層の具体的なインタフェースと実装クラスコード.
容量4のブロックキューLinkedBlockingDequeを作成し、ExecutorCompletionServiceインスタンスnewを使用してsubmitメソッドで4つのスレッドを作成します.各スレッドは関連する資料を検証し、1つのスレッドが検証されない場合はビジネスユーザーに戻って失敗を追加します.
   /**
     *   
     */
  ResultMessage addChannel(Map channelCorpTemp);
   /**
     *               
     */
       /**
  private int corePoolSize = 3;
    private int maximumPoolSize = 15;
    private long keepAliveTime = 10;
    BlockingQueue workQueue = new LinkedBlockingDeque<>(10);
    private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
            TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.AbortPolicy());

   /**
     *      
     */
       /**
     * showdoc
     *
     * @param entityMap    Map        
     * @return {"code":"200","message":"    ","data":[{"...":"..."}]}
     * @catalog   /     
     * @title   -       
     * @description        
     * @method POST
     * @url http://b.youlanw.com/api/qhCorp/channel/addCustomer
     * @remark
     * @number 99
     */
    @Override
    @Transactional(rollbackFor = SqlException.class)
    public ResultMessage addCustomer(Map entityMap) {
        QhChannelCorpCustomerTemp customerTemp = RedisConvertUtil.mapToObject(entityMap, QhChannelCorpCustomerTemp.class);
        //    code
        String companyCode = UUID.randomUUID().toString().replace("-", "");
        customerTemp.setCorpCode(companyCode);
        //map Object
        CorpPhotoVo supplementVo = RedisConvertUtil.mapToObject(entityMap, CorpPhotoVo.class);
        Date now = DateConvertUtils.getNow();
        //   id  
        if (customerTemp.getId() != null) { //           
            boolean updateResult = updateCustomerTempInfoWithFailed(customerTemp, supplementVo);
            redisUtil.removeZset(ChannelCorpRedisKey.CORP + customerTemp.getCorpUserId() + ChannelCorpRedisKey.CHECKFAILED, customerTemp.getId());
            if (!updateResult) {
                return new ResultMessage(SysCode.FAILUE.getCode(), "           !");
            }
        } else { //           
            final Long corpUserId = customerTemp.getCorpUserId();
            final String creditCode = customerTemp.getCreditCode();
            BlockingQueue>> bq = new LinkedBlockingQueue<>(4);
            CompletionService> cs = new ExecutorCompletionService<>(threadPool, bq);
            //                
            cs.submit(() -> isChannelHasCustomer(corpUserId, creditCode));
            //             (   ,    )
            cs.submit(() -> isChannelExist(creditCode));
            //              (    ,        )
            cs.submit(() -> isParentHasCustomer(corpUserId, creditCode));
            //t           ,         (    ,        )
            cs.submit(() -> isOtherSubAccountHasCustomer(corpUserId, creditCode));
            for (int i = 0; i < 4; i++) {
                TwoTuple r = null;
                try {
                    r = cs.take().get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                if (r.first)
                    return new ResultMessage(SysCode.FAILUE.getCode(), r.second);
            }
            insertCustomerTemp(customerTemp, supplementVo);
        }
        // redis         
        redisUtil.add(ChannelCorpRedisKey.CORP + customerTemp.getCorpUserId() + ChannelCorpRedisKey.CHECKING, customerTemp.getId(), -now.getTime());
        return new ResultMessage(ChannelCorpTempResponseCode.CHANNEL_CUSTOMER_ADD_SUCCESS.getCode(), "             !");
    }

3.serviceは、レイヤで呼び出された検証方法を実装する.
//  1
 private TwoTuple isChannelHasCustomer(Long corpUserId, String creditCode) {
        Map params = new HashMap<>();
        params.put("corpUserId", corpUserId);
        params.put("creditCode", creditCode);
        List count = customerTempMapper.findPage(params);
        if (count != null && count.size() > 0)
            return new TwoTuple<>(true, "          ,      !");
        return new TwoTuple<>(false, "          ");
    }
     /**
     *       ,             
     *
     * @return true:  
     */
    @ServiceImplParamAnnotation("creditCode")
    public TwoTuple isChannelExist(String creditCode) {
        Map params = new HashMap<>();
        params.put("creditCode", creditCode);
        params.put("state", ChannelTempCorpStateEnum.CHECK_SUCCESS);
        List page = channelTempMapper.findPage(params);
        if (page != null && page.size() > 0) {
            return new TwoTuple<>(true, "success");
        }
        return new TwoTuple<>(false, "failed");
    }
 /**
     *             
     *
     * @param corpUserId      id
     * @return true: 
     */
    private TwoTuple isParentHasCustomer(Long corpUserId, String creditCode) {
        Long count = customerMapper.isParentHasCustomer(corpUserId, creditCode);
        if (!(count == null || count.intValue() == 0))
            return new TwoTuple<>(true, "           !");
        return new TwoTuple<>(false, "          !");
    }
     /**
     *            ,         (    ,        )
     *
     * @return true: 
     */
    private TwoTuple isOtherSubAccountHasCustomer(Long corpUserId, String creditCode) {
        //            id
        List otherSubAccountIds = channelUserFeign.getAllOtherSubAccountId(corpUserId);
        if (otherSubAccountIds == null || otherSubAccountIds.size() == 0) return new TwoTuple<>(false, "      ");
        Map params = new HashMap<>();
        params.put("corpUserIds", otherSubAccountIds);
        params.put("creditCode", creditCode);
        Long count = customerMapper.isOtherSubAccountHasCustomer(params);
        if (!(count == null || count.intValue() == 0))
            return new TwoTuple<>(true, "                !");
        return new TwoTuple<>(false, "           ");
    }