Samtidighed på jvm
-
Upload
niels-bech-nielsen -
Category
Technology
-
view
270 -
download
1
Transcript of Samtidighed på jvm
Concurrency on the JVM15 min introduktion til samtidighed
Niels Bech [email protected]
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
Behovet for samtidighed
● Bruger respons○ Single-threaded UI
● Udnyttelse af multi-core arkitektur○ Parallel arkitektur
● Resourceudnyttelse○ Eksempelvis parallel I/O
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)
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)
Example
Pattern for Task Scheduling
Net Asset Value (NAV) = summen af (aktie * gældende kurs)
Samtidighedsproblem
● Samtidighedsproblemer er ○ altid non-deterministisk○ Som regel sporadisk○ Svære at se i koden
● Optræder når○ Mere end én tråd○ Arbejder på fælles data○ Mindst en tråd skriver til data
Fjern en betingelse og problemet er løst
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
Shared mutability
● Shared mutability kan ikke undgåes● Har få værktøjer i java
○ volatile○ AtomicXXX○ synchronized○ Locks
Deling eksempel
Users*
Software Transactional Memory
● Baseret på databaseteknologi○ A)tomic○ C)onsistent○ I )solated○ D)urable
● Skrivninger foregår i en transaktion○ idempotent○ Uden side-effekt
● Automatic retry on rollback● Anvendt i visse funktionelle sprog
○ f.eks. clojure
Not necessary
Clojure
● Separation mellem reference og tilstand○ Tilstand er immutable○ Kun Identity Objects (ref) er skrivbare
● Referencer kan kun ændres i en transaktion
Balance
100
200
Transacted
Simpel clojure eksempel
(def balance (ref 0))
(println "Balance is " @balance)
(dosync (ref-set balance 100))
(println "Balance is now " @balance)
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))
STM i Java
● Man kan anvende clojure direkte i java○ import clojure.lang.Ref;
● STM også implementeret i andre libraries○ e.g. Multiverse
STM Usage
● Atomare skrivninger med automatisk retry○ Idempotent operations○ Ingen side-effekter
● Simpel, garanteret datakonsistens● Bedst til få skrivninger og mange læsninger
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)
Actor livscyklus
Created
Started
Stopped
Ready Running
Active
Scala Untyped Actorclass 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 }}
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 }}
Typed Actor
Wrap objektinstans som actorAlle metodekald bliver håndteret asynkrontI scala bruges scala traits som typeGiver et objekt med isolated mutability
Actors
● Bryder traditionel sekvensprogrammering○ events etc
● Derfor velegnet til multi-core paradigme
Sammenfatning
Skaler dine opgaver til parallel udførsel
● 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
poolsize = number of cores / (1 - blocking coefficient)