Concurrency and Source Panels
Synchronized Counter
Protect a shared counter update with a synchronized block.
synchronized
A synchronized block lets only one thread update the shared value at a time, keeping the final count predictable.
Synchronized Counter
SynchronizedCounter.scala
Replay: real traced execution (multi-file project)
object Main {
val lock = new Object()
var counter = 0
def add(amount: Int): Unit = {
lock.synchronized {
counter = counter + amount
}
}
def main(args: Array[String]): Unit = {
val amount = 2
val first = Thread(() => add(amount))
val second = Thread(() => add(amount + 1))
first.start()
second.start()
first.join()
second.join()
println("amount=" + amount)
println("counter=" + counter)
}
}
object Main {
val lock = new Object()
var counter = 0
def add(amount: Int): Unit = {
lock.synchronized {
counter = counter + amount
}
}
def main(args: Array[String]): Unit = {
val amount = 1
val first = Thread(() => add(amount))
val second = Thread(() => add(amount + 1))
first.start()
second.start()
first.join()
second.join()
println("amount=" + amount)
println("counter=" + counter)
}
}
object Main {
val lock = new Object()
var counter = 0
def add(amount: Int): Unit = {
lock.synchronized {
counter = counter + amount
}
}
def main(args: Array[String]): Unit = {
val amount = 4
val first = Thread(() => add(amount))
val second = Thread(() => add(amount + 1))
first.start()
second.start()
first.join()
second.join()
println("amount=" + amount)
println("counter=" + counter)
}
}
amount ← 2, first ← Thread[#19,Thread-0,5,main], second ← Thread[#20,Thread-1,5,main]
11def main(args: Array[String]): Unit = {12 val amount→ 2 = 2 //@amount=1, 41314 val first→ Thread[#19,Thread-0,5,main] = Thread(() => add(amount))15 val second→ Thread[#20,Thread-1,5,main] = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 second.start()19 first.join()def add(amount: Int): Unit =
pass 1 of 25def add(amount2: Int): Unit = {6 lock.synchronized {first.start()
5def add(amount: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter0 + amount28 }9}1011def main(args: Array[String]): Unit = {12 val amount = 2 //@amount=1, 41314 val first = Thread(() => add(amount))15 val second = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 secondThread[#20,Thread-1,5,main].start()19 first.join()20 second.join()def add(amount: Int): Unit =
pass 2 of 25def add(amount3: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter2 + amount38 }9}second ← Thread[#20,Thread-1,5,]
17 first.start()18 second→ Thread[#20,Thread-1,5,].start()19 firstThread[#19,Thread-0,5,].join()20 secondThread[#20,Thread-1,5,].join()2122 println("amount=" + amount2)23 println("counter=" + counter5)24 }25}outputamount=2 counter=5
amount ← 1, first ← Thread[#19,Thread-0,5,main], second ← Thread[#20,Thread-1,5,main]
11def main(args: Array[String]): Unit = {12 val amount→ 1 = 11314 val first→ Thread[#19,Thread-0,5,main] = Thread(() => add(amount))15 val second→ Thread[#20,Thread-1,5,main] = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 second.start()19 first.join()def add(amount: Int): Unit =
pass 1 of 25def add(amount1: Int): Unit = {6 lock.synchronized {first.start()
5def add(amount: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter0 + amount18 }9}1011def main(args: Array[String]): Unit = {12 val amount = 11314 val first = Thread(() => add(amount))15 val second = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 secondThread[#20,Thread-1,5,main].start()19 first.join()20 second.join()def add(amount: Int): Unit =
pass 2 of 25def add(amount2: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter1 + amount28 }9}second ← Thread[#20,Thread-1,5,]
17 first.start()18 second→ Thread[#20,Thread-1,5,].start()19 firstThread[#19,Thread-0,5,].join()20 secondThread[#20,Thread-1,5,].join()2122 println("amount=" + amount1)23 println("counter=" + counter3)24 }25}outputamount=1 counter=3
amount ← 4, first ← Thread[#19,Thread-0,5,main], second ← Thread[#20,Thread-1,5,main]
11def main(args: Array[String]): Unit = {12 val amount→ 4 = 41314 val first→ Thread[#19,Thread-0,5,main] = Thread(() => add(amount))15 val second→ Thread[#20,Thread-1,5,main] = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 second.start()19 first.join()def add(amount: Int): Unit =
pass 1 of 25def add(amount4: Int): Unit = {6 lock.synchronized {first.start()
5def add(amount: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter0 + amount48 }9}1011def main(args: Array[String]): Unit = {12 val amount = 41314 val first = Thread(() => add(amount))15 val second = Thread(() => add(amount + 1))1617 firstThread[#19,Thread-0,5,main].start()18 secondThread[#20,Thread-1,5,main].start()19 first.join()20 second.join()def add(amount: Int): Unit =
pass 2 of 25def add(amount5: Int): Unit = {6 lock⟨Object A⟩.synchronized {7 counter = counter4 + amount58 }9}second ← Thread[#20,Thread-1,5,]
17 first.start()18 second→ Thread[#20,Thread-1,5,].start()19 firstThread[#19,Thread-0,5,].join()20 secondThread[#20,Thread-1,5,].join()2122 println("amount=" + amount4)23 println("counter=" + counter9)24 }25}outputamount=4 counter=9