Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Samtidighed på jvm
1. Concurrency on the JVM
15 min introduktion til samtidighed
Niels Bech Nielsen
nbn@logical.dk
2. Om...
● 20+ års erfaring med objektorienteret
systemudvikling
● Undervist på datamatiker- og
datanomuddannelsen
● Tidligere Global Chief Engineer @ JP
Morgan Rates i Glasgow
○ Intraday Risk Management
○ Trade capture
3. Behovet for samtidighed
● Bruger respons
○ Single-threaded UI
● Udnyttelse af multi-core arkitektur
○ Parallel arkitektur
● Resourceudnyttelse
○ Eksempelvis parallel I/O
4. Java samtidighed
● Frem til Java 5 meget primitiv håndtering
○ Manuel (og farlig) trådhåndtering
○ Objekt-Monitor synkronisering
○ Wait-Notify paradigme
● Java 5++
○ Executors, Callables, Futures
○ ReadWriteLocks
○ (Fork-Join)
5. Task scheduling
● Bedst udnyttelse baseret på
○ Antal processor/cores
■ Runtime.getRuntime().availableProcessors();
○ Blocking coefficiency
■ Graden af blokerende I/O operationer
poolsize = number of cores / (1 - blocking coefficient)
7. Samtidighedsproblem
● Samtidighedsproblemer er
○ altid non-deterministisk
○ Som regel sporadisk
○ Svære at se i koden
● Optræder når
○ Mere end én tråd Fjern en betingelse og
○ Arbejder på fælles data problemet er løst
○ Mindst en tråd skriver til data
8. Deling af tilstand
● Shared mutability
○ Alle tråde kan tilgå og skrive til data direkte
● Isolated mutability
○ Kun 1 tråd tilgår og skriver til data
● Immutability
○ Skrevne data kan ikke ændres
○ brugen af final
○ copy on write collections
○ Linked Lists, Tries
9. Shared mutability
● Shared mutability kan ikke undgåes
● Har få værktøjer i java
○ volatile
○ AtomicXXX
○ synchronized
○ Locks
11. Software Transactional Memory
● Baseret på databaseteknologi
○ A)tomic
○ C)onsistent
○ I )solated
○ D)urable Not necessary
● Skrivninger foregår i en transaktion
○ idempotent
○ Uden side-effekt
● Automatic retry on rollback
● Anvendt i visse funktionelle sprog
○ f.eks. clojure
12. Clojure
● Separation mellem reference og tilstand
○ Tilstand er immutable
○ Kun Identity Objects (ref) er skrivbare
● Referencer kan kun ændres i en transaktion
100
Balance
200
Transacted
13. Simpel clojure eksempel
(def balance (ref 0))
(println "Balance is " @balance)
(dosync
(ref-set balance 100)
)
(println "Balance is now " @balance)
14. Write skew
● Clojure transaktioner sikrer mod samtidige
skrivninger fra flere tråde
● Læsning er uden for transaktion
○ Seneste committede værdi
(def checking-account (ref 500))
(def savings-account (ref 600))
(defn withdraw-account [from-balance constraining-balance amount]
(dosync
(let [total-balance (+ @from-balance @constraining-balance)]
(if (>= (- total-balance amount) 1000)
(alter from-balance - amount)
(println "Sorry can't withdraw due to insufficient funds")
)
)
)
)
(future (withdraw-account checking-account savings-account 100))
(future (withdraw-account savings-account checking-account 100))
15. STM i Java
● Man kan anvende clojure direkte i java
○ import clojure.lang.Ref;
● STM også implementeret i andre libraries
○ e.g. Multiverse
16. STM Usage
● Atomare skrivninger med automatisk retry
○ Idempotent operations
○ Ingen side-effekter
● Simpel, garanteret datakonsistens
● Bedst til få skrivninger og mange læsninger
17. Actors paradigme
● Beskedbaseret kommunikation mellem
objekter
● En Actor
○ har sin egen beskedkø
○ Udfører kald sekventielt
● Kald til actor
○ Som udgangspunkt asynkron
○ Blokerer ved synkrone kald
● Alle actors deler en threadpool
● Meget benyttet i Erlang og Scala
○ Scala har flere actor libraries
○ Kommende eksempler bruger akka (jboner)
19. Scala Untyped Actor
class HollywoodActor extends Actor {
def receive = {
case role =>
println "Playing " + role
}
}
object HollywoodActor {
def main(args: Array[String]) : Unit = {
val johnnyDepp = Actor.actorOf[HollywoodActor].start()
johnnyDepp ! "Jack Sparrow"
johnnyDepp ! "Edward Scissorhands"
johnnyDepp ! "Willy Wonka"
Actors.registry.shutdownAll
}
}
20. Scala Untyped Actor (synkron)
class FortuneTeller extends Actor {
def receive = {
case name : String =>
self.reply_?(String.format("%s, your future is bright", name))
}
}
object FortuneTeller {
def main(args: Array[String]) : Unit = {
val nostradamus = Actor.actorOf[FortuneTeller].start()
nostradamus ! "Niels"
val response = nostradamus !! "Martin"
response match {
case Some(responseMessage) => println(responseMessage)
case None => println ("Never got a response before timeout")
}
Actors.registry.shutdownAll
}
}
21. Typed Actor
Wrap objektinstans som actor
Alle metodekald bliver håndteret asynkront
I scala bruges scala traits som type
Giver et objekt med isolated mutability
23. Sammenfatning
Skaler dine opgaver til parallel udførsel
poolsize = number of cores / (1 - blocking coefficient)
● Java har fået meget bedre værktøjer til
samtidighedsprogrammering, men...
○ STM kan med fordel anvendes ved større read-
intensive datamodeller
○ Actors bryder traditionel sekvensprogrammering og
isolerer udførsel via (primært) asynkrone beskeder