This is all very well and refCt will be atomic in itself but the value could change in such a way that closing the resource would not be closed - e.g. another thread decrementing the count prior to the conditional.
AtomicInteger
is (like it's name) is fully atomic. The method decrementAndGet()
seems like 2 operations but it is not. Just one thread will see the decremented AtomicInteger
as being 0. The only problem would be if you are decrementing it elsewhere.
Another possibility is that threads are incrementing and then decrementing all of the time. So there could be some issues where the DBUtil
is closing but then has to open again or something. You may then need a lock but the lock can just be around the DBUtil
call and not the AtomicInteger
decrement.
2) Overkill(?) example:
Yes I think so. You shouldn't need the lock unless the lock is needed to control access to the DBUtil
.
3) Should I actually use the AtomicInteger itself to manage the conditional through #compareAndSet and avoid blocking?
I see no need to do this. Internally the AtomicInteger
takes care of the decrementing race conditions. Here's the code for decrementAndGet()
:
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
4) Is this all more complicated than it should be / Can I not see the wood for the trees?
See above.