protected void addAndStartConsumers(int delta) {
   synchronized (this.consumersMonitor) {
     if (this.consumers != null) {
       for (int i = 0; i < delta; i++) {
         BlockingQueueConsumer consumer = createBlockingQueueConsumer();
         this.consumers.put(consumer, true);
         AsyncMessageProcessingConsumer processor = new AsyncMessageProcessingConsumer(consumer);
         this.taskExecutor.execute(processor);
         try {
           FatalListenerStartupException startupException = processor.getStartupException();
           if (startupException != null) {
             this.consumers.remove(consumer);
             throw new AmqpIllegalStateException(
                 "Fatal exception on listener startup", startupException);
           }
         } catch (InterruptedException ie) {
           Thread.currentThread().interrupt();
         } catch (Exception e) {
           consumer.stop();
           logger.error("Error starting new consumer", e);
           consumers.remove(consumer);
         }
       }
     }
   }
 }
 private void restart(BlockingQueueConsumer consumer) {
   synchronized (this.consumersMonitor) {
     if (this.consumers != null) {
       try {
         // Need to recycle the channel in this consumer
         consumer.stop();
         // Ensure consumer counts are correct (another is going
         // to start because of the exception, but
         // we haven't counted down yet)
         this.cancellationLock.release(consumer);
         this.consumers.remove(consumer);
         consumer = createBlockingQueueConsumer();
         this.consumers.add(consumer);
       } catch (RuntimeException e) {
         logger.warn(
             "Consumer failed irretrievably on restart. " + e.getClass() + ": " + e.getMessage());
         // Re-throw and have it logged properly by the caller.
         throw e;
       }
       this.taskExecutor.execute(new AsyncMessageProcessingConsumer(consumer));
     }
   }
 }
 private void restart(BlockingQueueConsumer consumer) {
   synchronized (this.consumersMonitor) {
     if (this.consumers != null) {
       try {
         // Need to recycle the channel in this consumer
         consumer.stop();
         // Ensure consumer counts are correct (another is going
         // to start because of the exception, but
         // we haven't counted down yet)
         this.cancellationLock.release(consumer);
         this.consumers.remove(consumer);
         consumer = createBlockingQueueConsumer();
         this.consumers.add(consumer);
       } catch (RuntimeException e) {
         logger.warn("Consumer died on restart. " + e.getClass() + ": " + e.getMessage());
         // Thrown into the void (probably) in a background thread.
         // Oh well, here goes...
         throw e;
       }
       this.taskExecutor.execute(new AsyncMessageProcessingConsumer(consumer));
     }
   }
 }
    public void run() {

      boolean aborted = false;

      try {

        try {
          consumer.start();
          start.countDown();
        } catch (FatalListenerStartupException ex) {
          throw ex;
        } catch (Throwable t) {
          start.countDown();
          handleStartupFailure(t);
          throw t;
        }

        // Always better to stop receiving as soon as possible if
        // transactional
        boolean continuable = false;
        while (isActive() || continuable) {
          try {
            // Will come back false when the queue is drained
            continuable = receiveAndExecute(consumer) && !isChannelTransacted();
          } catch (ListenerExecutionFailedException ex) {
            // Continue to process, otherwise re-throw
          }
        }

      } catch (InterruptedException e) {
        logger.debug("Consumer thread interrupted, processing stopped.");
        Thread.currentThread().interrupt();
        aborted = true;
      } catch (FatalListenerStartupException ex) {
        logger.error("Consumer received fatal exception on startup", ex);
        this.startupException = ex;
        // Fatal, but no point re-throwing, so just abort.
        aborted = true;
      } catch (FatalListenerExecutionException ex) {
        logger.error("Consumer received fatal exception during processing", ex);
        // Fatal, but no point re-throwing, so just abort.
        aborted = true;
      } catch (Throwable t) {
        if (logger.isDebugEnabled()) {
          logger.warn(
              "Consumer raised exception, processing can restart if the connection factory supports it",
              t);
        } else {
          logger.warn(
              "Consumer raised exception, processing can restart if the connection factory supports it. "
                  + "Exception summary: "
                  + t);
        }
      }

      // In all cases count down to allow container to progress beyond startup
      start.countDown();

      if (!isActive() || aborted) {
        logger.debug("Cancelling " + consumer);
        try {
          consumer.stop();
        } catch (AmqpException e) {
          logger.info("Could not cancel message consumer", e);
        }
        if (aborted) {
          logger.info("Stopping container from aborted consumer");
          stop();
        }
      } else {
        logger.info("Restarting " + consumer);
        restart(consumer);
      }
    }