I have the following three variants of Scala code that take as input some method and calls it atomically. The method could have some db/read write operations among other things. I don't know in advance what method it will be except that it terminates in < 100 millis. Pasting Scala code for brevity but imagining a Java version should be straightforward.
val locked = new java.util.concurrent.atomic.AtomicBoolean(false)
def usingAtoimcSleepLock[T](f: => T):T = {
while (! locked.compareAndSet(false, true)) {Thread.sleep(10)}
try f
finally locked.set(false)
}
def usingAtoimcSpinLock[T](f: => T):T = {
while (! locked.compareAndSet(false, true)) { /* do nothing */ }
try f
finally locked.set(false)
}
def usingAtoimcTimeoutLock[T](f: => T):T = {
var ctr = 0
while (! locked.compareAndSet(false, true)) {
if (ctr > 1000) throw new Exception("lock could not be opened")
ctr = ctr + 1
// can add Thread.sleep
}
try f
finally locked.set(false)
}
Which of the above 3 methods is recommended? In particular is usingAtomicSpinLock
recommended?
I feel usingAtomicTimeoutLock
with a Thread.sleep
is the best option. However, I also feel it could waste time due to context switching.
EDIT: I am not asking "what objects should I synchronize?". What I want to know is "how should I synchronize the objects (that I know)"?