Description
I might have found an error. Happy to submit errata @ http://packtpub.com/submit-errata, if I am right.
This concerns a snippet of code on the book, not on the exercises.
On chapter 2, section Volatile variables
, page 53 (on paper print of 1st edition) you have the following snippet of code to illustrate volatile variables:
class Page(val txt: String, var position: Int)
object Volatile extends App {
val pages = for (i <- 1 to 5) yield
new Page("Na" * (100 - 20 * i) + " Batman!", -1)
@volatile var found = false
for (p <- pages) yield thread {
var i = 0
while (i < p.txt.length && !found)
if (p.txt(i) == '!') {
p.position = i
found = true
} else i += 1
}
while (!found) {}
log(s"results: ${pages.map(_.position)}")
}
On the following page, you say:
For the purposes of this example, the main thread busy-waits until it reads found, which is
true. It then prints the positions. Note that a write to position occurs before the write to
found in the spawned threads, which in turn occurs before reading found in the main
thread. This means that the main thread always sees the write of the thread that set found,
and hence prints at least one position other than -1.
This makes total sense.
However, shouldn't the variable position
on class Page
also be volatile?
I am concerned about a scenario on which a spawned thread finds an exclamation point, but the main thread prints the position -1.
Is there anything forbidding the following scenario:
- A spawned thread finds an exclamation point.
- It updates the variable position only to the local caches, not to main memory because position is not volatile.
- It updates variable
found
to main memory. - The main thread reads
found
to be true. - The main thread prints the results, but the page which was found to contain an exclamation point by the spawned thread still has the
-1
on the position variable.