title: Deadlock while add() and take() elements to BlockingQueue
body: <p>I'm playing with <code>java.util.concurrent</code> package and using its interface/classes to know how they work. I created a <code>BlockingQueue</code> instance (<code>ArrayBlockingQueue</code> imlpementation). And created 50 consumers and 50 producers of <code>Rannable</code> type. Then with <code>Executors.newFixedThreadPool(4)</code> created a thread pool of size 4 and submitted all of my consumers/producers to the <code>threadPool</code> (ExecutorService). But eventually printing the process I figured that it's <code>deadlock</code>-ing. Can anyone please explain why a thread safe queue gets deadlocked!? Below is my code:</p>
  
  <p><strong>Consumer:</strong></p>
  
  <pre><code>public class ArrayBlockingQueueConsumer implements Runnable{
  
      BlockingQueue&lt;Integer&gt; blockingQueue;
      int consumerNumber = 0;
  
      public ArrayBlockingQueueConsumer(BlockingQueue&lt;Integer&gt; blockingQueue, int consumerNumber) {
          this.blockingQueue = blockingQueue;
          this.consumerNumber = consumerNumber;
      }
  
      public void run() {
          int i = 0;
          while(i&lt;60) {
              System.out.printf("Consumer %d going take %d from blocking queue\n", consumerNumber, i);
              try {
                  int x = blockingQueue.take();
                  System.out.println("The number " + x + "is taken from the queue.");
              } catch (InterruptedException e) {
                  System.out.printf("Consumer %d interrupted while adding %d to blocking queue\n", consumerNumber, i);
                  e.printStackTrace();
              }
              i++;
          }
      }
  }
  </code></pre>
  
  <p><strong>Producer:</strong></p>
  
  <pre><code>public class ArrayBlockingQueueProducer implements Runnable{
  
      BlockingQueue&lt;Integer&gt; blockingQueue;
      int producerNumber = 0;
  
      public ArrayBlockingQueueProducer(BlockingQueue&lt;Integer&gt; blockingQueue, int producerNumber) {
          this.blockingQueue = blockingQueue;
          this.producerNumber = producerNumber;
      }
  
      public void run() {
          int i = 0;
          while(i&lt;60) {
              System.out.printf("Consumer %d going to add %d to blocking queue\n", producerNumber, i);
              blockingQueue.add(i);
              System.out.printf("Consumer %d added %d to blocking queue\n", producerNumber, i);
              i++;
          }
      }
  
  }
  </code></pre>
  
  <p><strong>Executor Class (main() method class):</strong></p>
  
  <pre><code>public class BlockingQueueExecutor {
  
      public static void main(String[] args) {
          BlockingQueue&lt;Integer&gt; blockingQueue = new ArrayBlockingQueue&lt;Integer&gt;(50);
  
          ArrayBlockingQueueConsumer[] consumers = new ArrayBlockingQueueConsumer[200];
          ArrayBlockingQueueProducer[] producers = new ArrayBlockingQueueProducer[200];
  
          System.out.println("Hello hello :D");
  
          for (int i = 0; i &lt; 200; i++) {
              consumers[i] = new ArrayBlockingQueueConsumer(blockingQueue, i+1);
              producers[i] = new ArrayBlockingQueueProducer(blockingQueue, i+1);
          }
  
          ExecutorService threadPool = Executors.newFixedThreadPool(4);
  
          for (int i = 0; i &lt; 200; i++) {
              threadPool.execute(consumers[i]);
              threadPool.execute(producers[i]);
          }
  
          threadPool.shutdown();
      }
  }
  </code></pre>
  
  <p>I ran the loops in consumers/producers from 0 to 60 so that they can throw exception when they don't find any element or find queue full respectively, ironically none of the producers/consumers threw any exception.</p>