/**
  * APNs通知結果生成
  *
  * <p>状態に応じた送信結果を生成して返却します
  *
  * @param apnsNotificationList 送信データ
  * @param isSuccess 正常フラグ
  * @param e 例外
  * @return 送信結果
  */
 private ApnsResult createApnsSendResult(
     List<ApnsNotification> apnsNotificationList, boolean isSuccess, Exception e) {
   ApnsResult apnsResult = new ApnsResult();
   for (ApnsNotification apnsNotification : apnsNotificationList) {
     switch (apnsNotification.getPushStatus()) {
       case NONE:
         apnsResult.addNone(apnsNotification);
         break;
       case DONE:
         apnsResult.addDone(apnsNotification);
         break;
       case ERROR:
         apnsResult.addError(apnsNotification);
         break;
     }
   }
   apnsResult.setSuccess(isSuccess);
   apnsResult.setException(e);
   return apnsResult;
 }
  /**
   * PUSH通知(マルチスレッド送信)
   *
   * <p>分割単位ごとにマルチスレッドでPUSH通知します。<br>
   *
   * @param apnsNotificationList 送信データリスト
   * @param threadCount スレッド数
   * @return 送信結果
   */
  public synchronized ApnsResult push(
      List<ApnsNotification> apnsNotificationList, int threadCount) {
    logger.info("PUSH通知(マルチスレッド送信) - 開始");

    // 送信完了を待機して各スレッドの送信結果を取得
    ApnsResult apnsResult = new ApnsResult();

    try {
      // スレッド数が1の場合はシングルスレッド送信
      if (threadCount == 1) {
        logger.info("スレッド数が1のため、シングルスレッドで実行します。");
        return push(apnsNotificationList);
      }

      // Listをスレッド数に応じて分割
      List<List<ApnsNotification>> apnsNotificationListList =
          ApnsUtil.splitList(apnsNotificationList, threadCount);

      logger.info("スレッド数:{}", apnsNotificationListList.size());

      // 非同期処理用ExecutorService生成
      ExecutorService service = Executors.newFixedThreadPool(apnsNotificationListList.size());
      List<Future<ApnsResult>> futureList = new ArrayList<Future<ApnsResult>>();

      // 非同期PUSH送信
      for (List<ApnsNotification> apnsNotificationThreadList : apnsNotificationListList) {
        ApnsNotificationPushCaller caller =
            new ApnsNotificationPushCaller(apnsNotificationThreadList);
        Future<ApnsResult> future = service.submit(caller);
        futureList.add(future);
      }

      // シャットダウン宣言
      service.shutdown();

      apnsResult.setSuccess(true);
      for (int i = 0; i < futureList.size(); i++) {
        // 待機&結果取得
        ApnsResult r = futureList.get(i).get();

        // 1つでも異常終了があれば異常とする
        if (!r.isSuccess()) {
          apnsResult.setSuccess(r.isSuccess());
        }

        // 複数スレッドでExceptionがあった場合は最後のものを格納
        if (r.getException() != null) {
          apnsResult.setException(r.getException());
        }

        // 未実行リスト
        apnsResult.addAllNone(r.getNoneList());
        // 実行済リスト
        apnsResult.addAllDone(r.getDoneList());
        // エラーリスト
        apnsResult.addAllError(r.getErrorList());
      }
    } catch (Exception e) {
      apnsResult.setException(e);
      apnsResult.setSuccess(false);
    } finally {
      logger.info("PUSH通知(マルチスレッド送信) - 終了");
    }
    return apnsResult;
  }