arxdjn (2) [Avatar] Offline
#1
Apologies for the subject line – I am almost certainly missing something obvious, so I’d appreciate someone enlightening me as to what that is smilie I’m looking at the ImmutableService example on p. 32 (section 2.3.2 Concurrency) of the PDF version of the book. The code is as follows:

class ImmutableService[Key, Value] extends Service[Key, Value] {
var currentIndex = new ImmutableHashMap[Key,Value]
def lookUp(k : Key) : Option[Value] = currentIndex.get(k)
def insert(k : Key, v: Value) : Unit = synchronized {
currentIndex = currentIndex + ((k, v))
}
}

Consider two threads, each running on a separate processor. Thread A (running on CPU 1) calls lookUp. Thread B (running on CPU 2) then calls insert. Thread A (still running on CPU 1) then calls lookUp again.

I’m no expert in the Java Memory Model (JMM), but I can’t see that it provides any guarantee that thread A won’t see a stale version of currentIndex in its second call (e.g. if the previous value of currentIndex happens to be in the processor cache on CPU 1). As far as I understand it, Thread A is only guaranteed to see the latest value of currentIndex written by Thread B if Thread A synchronizes on the same monitor as did Thread B when the updated value of currentIndex was written.

Consequently, it seems to me that var currentIndex should be declared volatile for this example to work. Now, since Joshua Suereth is vastly more experienced than I am (my Java is rusty and I am new to Scala), there must be something I’m missing, and I’d like to know what that is -- any help would therefore be very much appreciated.

For more information, see ‘What does synchronization do?’ in the JSR 133 FAQ:

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

Specifically, that says:

"Important Note: Note that it is important for both threads to synchronize on the same monitor in order to set up the happens-before relationship properly. It is not the case that everything visible to thread A when it synchronizes on object X becomes visible to thread B after it synchronizes on object Y. The release and acquire have to "match" (i.e., be performed on the same monitor) to have the right semantics. Otherwise, the code has a data race."

The accepted answer on this Stack Overflow question also looks relevant:

http://stackoverflow.com/a/6948326

Many thanks in advance. I look forward to enlightenment!

--
Daniel
arxdjn (2) [Avatar] Offline
#2
Re: ImmutableService concurrency example broken?
My question has been answered in a thorough and helpful response here:

https://groups.google.com/d/topic/scala-user/ORxWFIzRb2c/discussion