Thread-safe stack in Java with fixed capacity Implement a multi-threaded stack, with freedom to use existing
  implementations of stack. On top of being thread-safe, it must block
  (not busy-wait) a pushing thread when stack is full and a popping
  thread when stack is empty. It must signal the threads out of sleep
  when stack has space again or elements to pop. Fairness is optional in this question.


How can I implement such a stack in Java? I came up with below implementation. Is this the correct way to solve above problem?

public class MyStack&lt;E&gt; {
  private final Stack&lt;E&gt; stack;
  private int max = 16;
  private final ReentrantLock lock = new ReentrantLock(true);
  private final Condition notEmpty = lock.newCondition();
  private final Condition notFull = lock.newCondition();

  public MyStack(int size) {
    this.stack = new Stack&lt;&gt;();
    this.max = size;
  }

  public void push(E e) {
    lock.lock();
    try {
      while (stack.size() == max) {
        notFull.await();
      }
      stack.push(e);
      notEmpty.signalAll();
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    } finally {
      lock.unlock();
    }
  }

  public E pop() {
    lock.lock();
    try {
      while (stack.size() == 0) {
        notEmpty.await();
      }
      E item = stack.pop();
      notFull.signalAll();
      return item;
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
}
Looks good to me on a cursory glance. It's pretty much the exact same code as in java.util.concurrent.locks.Condition JavaDoc.

The only definitive problem I see is the catching and logging of InterruptedException. The code acts towards the caller as if the operation succeeded while nothing was done.

Not providing a way to set the maximum wait time will be a limitation in a library intended for generic use.

Stylistically, private int max should be final to emphasize that it must not be changed after initialization (as changing it when threads are waiting would cause serious problems).

Another thing, which may be a matter of taste, is the stack.size() == max comparison. I always like to use &gt;= where a size is compared to a maximum limit (with a comment, of course). This gives an extra safeguard against infinite loops in the case where a programming error causes the collection to exceed maximum size.