CHAPTER 3 ■ COLLECTIONS AND THE JOY OF IMMUTABILITY
87
Concurrency Without Synchronization
Writing multithreaded programs is a challenge. While simple data structures such as
multithreaded queues or mailboxes are easy to write and relatively low in defects, most
Java programs don’t lend themselves to such simple abstractions. This is due in large part
to passing around mutable data structures. Any data structure that can be changed without
creating a new reference is a potential defect in a multithreaded application. The problem
is exacerbated by the transitory nature of thread-related defects: it’s hard to test for them.
There are many strategies for dealing with concurrency. One can synchronize every-
thing, but this often leads to deadlocks because two threads are locking resources that
depend on each other.
Another strategy is to copy everything that’s passed to a thread. This strategy uses
memory and CPU to work around the threading issue. Every time a resource is needed by
a thread, the resource is copied for the thread’s use. This means each
Array, Hashtable, and
so on that’s requested by a given thread is copied. That way, the current thread does not
have to synchronize the data.
Scala and immutable data structures offer another alternative. In this example, we’re
going to write a synchronize-free program (even the underlying data structures contain
no synchronization) that has 2,000 threads each updating shared data every 100 milli-
seconds and a master thread that summarizes the shared data structure every second.
Create a file called
Multics.scala and put the code from Listing 3-8 in it. We’ll go
through the code line by line after the listing.
Listing 3-8. Multics.scala
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.TreeHashMap
object Multics {
type MT = Map[String, Int]
val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
val clashCnt = new AtomicLong
def main(argv: Array[String]) {
runThread {
repeatEvery(1000) {
println("Clash Count: "+clashCnt+" Total: "+
info.get.foldLeft(0)(_ + _._2))
} }
19897ch03.fm Page 87 Thursday, April 16, 2009 4:54 PM