Shutdown method in queue implementations
My immediate thought is that this is an unacceptable implementation.  In particular, you seem to be trying to shutdown the threads accessing the queue by signally conditions, which I think confuses things badly.

See Concurrent Programming in Java, Second Edition by Doug Lea -- especially Chapter 3 ("State Dependence").

Consider this use case: you have a service, with multiple publishers (Runnables) and consumers (also Runnables); publishers offer items to the queue, consumers take items from it.  There's a UI, with a big red SHUTDOWN button on it.  When the user hits that button, what does the user want?

You seem to be implementing the idea that the user wants to shut down the queue.  But I put it to you that it's more accurate that the user wants to shut down the service itself.  The service itself maintains its own shutdown state, which the runnables can access.  Invoking service shutdown then does two things - (1) it sets the shutdown flag, so that the producer and consumer flags can see the change, and (2) it interrupts the producers and consumers, so that they look at the shutdown flag.

So the usual idiom would be to run the publishers and consumers in an ExecutorService, and after the shutdown flag has been set, ExecutorService.shutdownNow() would be invoked to signal the interruption to the running threads.  The threads that are parked on your conditions (queueNotFull.await()) throw InterruptedExceptions, and the handlers for these exceptions can then check the shutdown flag and do the right thing.

Condition.signalAll doesn't interrupt() the threads, it just gets them contending on the lock again.  When they get the lock, they just return from await; which means they check the while condition, and then put themselves back to sleep (Condition.await) because it is still true.

In short, Locks and Conditions are for co-ordination; if you are trying to implement cancellation, you should be using interrupts.