title: Deadlock in ThreadPoolExecutor
body: <p>Encountered a situation when <code>ThreadPoolExecutor</code> is parked in <code>execute(Runnable)</code> function while all the <code>ThreadPool</code> threads are waiting in <code>getTask</code> func, workQueue is empty. </p>
  
  <p>Does anybody have any ideas? </p>
  
  <p>The <code>ThreadPoolExecutor</code> is created with <code>ArrayBlockingQueue</code>, and <code>corePoolSize == maximumPoolSize = 4</code></p>
  
  <p>[Edit] To be more precise, the thread is blocked in <code>ThreadPoolExecutor.exec(Runnable command)</code> func. It has the task to execute, but doesn't do it.</p>
  
  <p>[Edit2] The executor is blocked somewhere inside the working queue (<code>ArrayBlockingQueue</code>).</p>
  
  <p>[Edit3] The callstack:</p>
  
  <pre><code>thread = front_end(224)
  at sun.misc.Unsafe.park(Native methord)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
  at
  java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
  at
  java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
  at
  java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
  at
  java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
  at java.util.concurrent.ArrayBlockingQueue.offer(ArrayBlockingQueue.java:224)
  at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:653)
  at net.listenThread.WorkersPool.execute(WorkersPool.java:45)
  </code></pre>
  
  <p>at the same time the workQueue is empty (checked using remote debug)</p>
  
  <p>[Edit4] Code working with <code>ThreadPoolExecutor</code>:</p>
  
  <pre><code>public WorkersPool(int size) {
    pool = new ThreadPoolExecutor(size, size, IDLE_WORKER_THREAD_TIMEOUT, TimeUnit.SECONDS, new ArrayBlockingQueue&lt;Runnable&gt;(WORK_QUEUE_CAPACITY),
        new ThreadFactory() {
          @NotNull
          private final AtomicInteger threadsCount = new AtomicInteger(0);
  
          @NotNull
          public Thread newThread(@NotNull Runnable r) {
            final Thread thread = new Thread(r);
            thread.setName("net_worker_" + threadsCount.incrementAndGet());
            return thread;
          }
        },
  
        new RejectedExecutionHandler() {
          public void rejectedExecution(@Nullable Runnable r, @Nullable ThreadPoolExecutor executor) {
            Verify.warning("new task " + r + " is discarded");
          }
        });
    }
  
    public void execute(@NotNull Runnable task) {
      pool.execute(task);
    }
  
    public void stopWorkers() throws WorkersTerminationFailedException {
      pool.shutdownNow();
      try {
        pool.awaitTermination(THREAD_TERMINATION_WAIT_TIME, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
        throw new WorkersTerminationFailedException("Workers-pool termination failed", e);
      }
    }
  }
  </code></pre>