I've refined this question a little, removing some of my understanding to try and make it as concise and specific as poss so it might come across as pretty basic
How should I use AtomicInteger as a reference counter to manage clean-up of some resource but in a safe and atomic way?
For instance:
1) Vanilla example:
public void close() {
if ((refCt.decrementAndGet()) == 0) {
DBUtil.close(conn);
}
}
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.
Use of a var (stack in thread) could ensure refCt is maintained in my thread, I guess but
2) Overkill(?) example:
public void close() {
synchronized(lock) {
if ((refCt.decrementAndGet()) == 0) {
DBUtil.close(conn);
}
}
}
My refCt is atomic in and of itself and my testing of the conditional (external to the AtomicInteger) is synchronised to safeguar atomicity.
3) Should I actually use the AtomicInteger itself to manage the conditional through #compareAndSet and avoid blocking?
public void close() {
for (;;) {
int current = refCt.get();
int refCtDec = current - 1;
if (compareAndSet(current, refCtDec))
DBUtil.close(conn);
}
}
4) Is this all more complicated than it should be / Can I not see the wood for the trees?