Concurrency and Source Panels
Atomic Ticket
Issue unique ticket numbers from multiple threads with AtomicInteger.
atomic update
Atomic types make a read-modify-write operation indivisible, so each thread receives a distinct ticket number.
Atomic Ticket
AtomicTicket.kt
Replay: real traced execution (multi-file project)
import java.util.concurrent.atomic.AtomicInteger
fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {
val ticket = next.getAndIncrement()
synchronized(lock) {
issued.add(ticket)
}
}
fun main() {
val start = 40
val next = AtomicInteger(start)
val issued = mutableListOf<Int>()
val lock = Any()
val first = Thread { issueTicket(next, issued, lock) }
val second = Thread { issueTicket(next, issued, lock) }
first.start()
second.start()
first.join()
second.join()
issued.sort()
println("start=$start")
println("issued=${issued.joinToString(",")}")
}
import java.util.concurrent.atomic.AtomicInteger
fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {
val ticket = next.getAndIncrement()
synchronized(lock) {
issued.add(ticket)
}
}
fun main() {
val start = 10
val next = AtomicInteger(start)
val issued = mutableListOf<Int>()
val lock = Any()
val first = Thread { issueTicket(next, issued, lock) }
val second = Thread { issueTicket(next, issued, lock) }
first.start()
second.start()
first.join()
second.join()
issued.sort()
println("start=$start")
println("issued=${issued.joinToString(",")}")
}
import java.util.concurrent.atomic.AtomicInteger
fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {
val ticket = next.getAndIncrement()
synchronized(lock) {
issued.add(ticket)
}
}
fun main() {
val start = 100
val next = AtomicInteger(start)
val issued = mutableListOf<Int>()
val lock = Any()
val first = Thread { issueTicket(next, issued, lock) }
val second = Thread { issueTicket(next, issued, lock) }
first.start()
second.start()
first.join()
second.join()
issued.sort()
println("start=$start")
println("issued=${issued.joinToString(",")}")
}
start ← 40, next ← 40, issued ← [], lock ← ⟨Object A⟩, first ← Thread[#19,Thread-0,5,main]
10fun main() {11 val start→ 40 = 40 //@start=10, 10012 val next→ 40 = AtomicInteger(start40)13 val issued→ [] = mutableListOf<Int>()14 val lock→ ⟨Object A⟩ = Any()1516 val first→ Thread[#19,Thread-0,5,main] = Thread { issueTicket(next, issued, lock) }17 val second→ Thread[#20,Thread-1,5,main] = Thread { issueTicket(next, issued, lock) }1819 firstThread[#19,Thread-0,5,main].start()20 secondThread[#20,Thread-1,5,main].start()21 first.join()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 1 of 23fun issueTicket(next40: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next.getAndIncrement()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 2 of 23fun issueTicket(next40: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next.getAndIncrement()next ← 41, ticket ← 40
3fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {4 val ticket→ 40 = next→ 41.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}910fun main() {11 val start = 40 //@start=10, 10012 val next = AtomicInteger(start)13 val issued = mutableListOf<Int>()14 val lock = Any()1516 val first = Thread { issueTicket(next, issued, lock) }17 val second = Thread { issueTicket(next, issued, lock) }1819 first.start()20 secondThread[#20,Thread-1,5,main].start()21 firstThread[#19,Thread-0,5,main].join()22 second.join()next ← 42, ticket ← 41
pass 1 of 23fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {4 val ticket→ 41 = next→ 42.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}pass 2 of 2 4val ticket = next.getAndIncrement()5synchronized(lock) {6 issued.add(ticket)7}first ← Thread[#19,Thread-0,5,]
20 second.start()21 first→ Thread[#19,Thread-0,5,].join()22 secondThread[#20,Thread-1,5,].join()2324 issued[40, 41].sort()25 println("start=$start40")26 println("issued=${issued[40, 41].joinToString(",")}")27}outputstart=40 issued=40,41
start ← 10, next ← 10, issued ← [], lock ← ⟨Object A⟩, first ← Thread[#19,Thread-0,5,main]
10fun main() {11 val start→ 10 = 1012 val next→ 10 = AtomicInteger(start10)13 val issued→ [] = mutableListOf<Int>()14 val lock→ ⟨Object A⟩ = Any()1516 val first→ Thread[#19,Thread-0,5,main] = Thread { issueTicket(next, issued, lock) }17 val second→ Thread[#20,Thread-1,5,main] = Thread { issueTicket(next, issued, lock) }1819 firstThread[#19,Thread-0,5,main].start()20 secondThread[#20,Thread-1,5,main].start()21 first.join()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 1 of 23fun issueTicket(next10: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next.getAndIncrement()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 2 of 23fun issueTicket(next10: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next10.getAndIncrement()5 synchronized(lock) {next ← 11, ticket ← 10
3fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {4 val ticket→ 10 = next→ 11.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}910fun main() {11 val start = 1012 val next = AtomicInteger(start)13 val issued = mutableListOf<Int>()14 val lock = Any()1516 val first = Thread { issueTicket(next, issued, lock) }17 val second = Thread { issueTicket(next, issued, lock) }1819 first.start()20 secondThread[#20,Thread-1,5,main].start()21 firstThread[#19,Thread-0,5,main].join()22 second.join()next ← 12, ticket ← 11
pass 1 of 23fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {4 val ticket→ 11 = next→ 12.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}pass 2 of 2 4val ticket = next.getAndIncrement()5synchronized(lock) {6 issued.add(ticket)7}first ← Thread[#19,Thread-0,5,]
20 second.start()21 first→ Thread[#19,Thread-0,5,].join()22 secondThread[#20,Thread-1,5,].join()2324 issued[10, 11].sort()25 println("start=$start10")26 println("issued=${issued[10, 11].joinToString(",")}")27}outputstart=10 issued=10,11
start ← 100, next ← 100, issued ← [], lock ← ⟨Object A⟩, first ← Thread[#19,Thread-0,5,main]
10fun main() {11 val start→ 100 = 10012 val next→ 100 = AtomicInteger(start100)13 val issued→ [] = mutableListOf<Int>()14 val lock→ ⟨Object A⟩ = Any()1516 val first→ Thread[#19,Thread-0,5,main] = Thread { issueTicket(next, issued, lock) }17 val second→ Thread[#20,Thread-1,5,main] = Thread { issueTicket(next, issued, lock) }1819 firstThread[#19,Thread-0,5,main].start()20 secondThread[#20,Thread-1,5,main].start()21 first.join()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 1 of 23fun issueTicket(next100: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next.getAndIncrement()second.start()
19first.start()20secondThread[#20,Thread-1,5,main].start()21first.join()fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: A…
pass 2 of 23fun issueTicket(next100: AtomicInteger, issued[]: MutableList<Int>, lock⟨Object A⟩: Any) {4 val ticket = next100.getAndIncrement()5 synchronized(lock) {next ← 102, ticket ← 101
3fun issueTicket(next: AtomicInteger, issued: MutableList<Int>, lock: Any) {4 val ticket→ 101 = next→ 102.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}910fun main() {11 val start = 10012 val next = AtomicInteger(start)13 val issued = mutableListOf<Int>()14 val lock = Any()1516 val first = Thread { issueTicket(next, issued, lock) }17 val second = Thread { issueTicket(next, issued, lock) }1819 first.start()20 second.start()21 firstThread[#19,Thread-0,5,main].join()22 second.join()pass 1 of 2 4 val ticket = next.getAndIncrement()5 synchronized(lock⟨Object A⟩) {6 issued.add(ticket)7 }8}pass 2 of 2 4val ticket = next.getAndIncrement()5synchronized(lock) {6 issued.add(ticket)7}first ← Thread[#19,Thread-0,5,]
20 second.start()21 first→ Thread[#19,Thread-0,5,].join()22 secondThread[#20,Thread-1,5,].join()2324 issued[100, 101].sort()25 println("start=$start100")26 println("issued=${issued[100, 101].joinToString(",")}")27}outputstart=100 issued=100,101