I don't normally review Java, but your code looks like it should work. You might consider using the
synchronised language feature instead in this instance, as you are not gaining anything from manually using
ReentrantReadWriteLock (e.g. you don't have anything which uses a
Read lock (e.g.
I appreciate that you want to use a minimal subset of the
JDK, but I'd still advocate a
Stack as the backing data-structure, since it (unsurprisingly) better represents the data, and in doing so reduces the opportunity for errors (e.g. ensuring you remove the topmost element, etc).
return null in
pop is not great, as your data-structure could just as well hold a
null; it should either
throw when you try to remove an element that doesn't exist, or you should provide some wrapper type which indicates whether a value was retrieved. At a minimum, the fact that the method returns
null when the queue is empty should be clearly documented.
return null is to remain, I'd move it (or indeed a
throw which replaces it) into an
else clause within the
try...catch, so that it is closer to the logic which determines it. Others might suggest inverting the
if, so that you
return null on
list.isEmpty(), and perform the meaningful operation otherwise.
"In finally" to the console might be useful for debugging, but as a consumer, this would infuriate me. Your class should provide a meaningful interface, and it shouldn't have any such unnecessary external influence.
You might consider making
final, which will ensure they are assigned within the constructor, and prevent their being overwritten by accident. The type isn't disposable, so there is no need to clear the references at any point.
Be consistent in your styling: you use
this.list, and then on the next line just
lock. You've also a random empty line half way through
push, with the rest of your code devoid of any spacing.