Slide 1

Slide 1 text

Concurrency and parallelism Friday, October 11, 13

Slide 2

Slide 2 text

Core Concepts • Concurrency • Parallelism • Shared State • Mutable Data Structures • Immutability • Shared Mutable State Friday, October 11, 13

Slide 3

Slide 3 text

Concurrency Hazards Friday, October 11, 13

Slide 4

Slide 4 text

Concurrency Hazards • Race Conditions • Deadlocks • Livelocks • Starvation Friday, October 11, 13

Slide 5

Slide 5 text

Threads Friday, October 11, 13

Slide 6

Slide 6 text

Starting a thread (.start (Thread. (fn [] ...))) Friday, October 11, 13

Slide 7

Slide 7 text

Executors Friday, October 11, 13

Slide 8

Slide 8 text

When a single thread won’t do (import '[java.util.concurrent Executors ExecutorService Callable]) (let [^ExecutorService pool (Executors/newFixedThreadPool 16) ^Callable callable (cast Callable (fn [] (reduce + (range 0 10000))))] (.submit pool callable)) Friday, October 11, 13

Slide 9

Slide 9 text

Approaches to concurrency Friday, October 11, 13

Slide 10

Slide 10 text

Approaches to Concurrency • Locking • Synchronisation • Transactions Friday, October 11, 13

Slide 11

Slide 11 text

Epochal Time Model Friday, October 11, 13

Slide 12

Slide 12 text

$100 $40 $50 -60$ +10$ Consumer Consumer Consumer Consumer Identity Time Dereferencing Mutation Friday, October 11, 13

Slide 13

Slide 13 text

STM atom Friday, October 11, 13

Slide 14

Slide 14 text

(def a (atom {})) a {} @reference value Friday, October 11, 13

Slide 15

Slide 15 text

(def a (atom {})) (swap! a assoc :b 1) a {} @reference value {:b 1} Friday, October 11, 13

Slide 16

Slide 16 text

(def a (atom {})) (swap! a assoc :b 1) a {} @reference value {:b 1} Friday, October 11, 13

Slide 17

Slide 17 text

(def a (atom {})) Initial Value Declaration Friday, October 11, 13

Slide 18

Slide 18 text

(swap! a assoc :b 1) Attributes Mutating Function Friday, October 11, 13

Slide 19

Slide 19 text

(def a (atom {})) (swap! a assoc :b 1) (swap! a assoc :c 2) a @reference value {:b 1} {:b 1 :c 2} Friday, October 11, 13

Slide 20

Slide 20 text

(def a (atom {})) (swap! a assoc :b 1) (swap! a assoc :c 2) a @reference value {:b 1} {:b 1 :c 2} Friday, October 11, 13

Slide 21

Slide 21 text

{:b 1} {:b 1 :c 2} Structural Sharing Friday, October 11, 13

Slide 22

Slide 22 text

Operations on Atoms Friday, October 11, 13

Slide 23

Slide 23 text

(deref my-atom) @my-atom Dereferences and returns current value of atom Friday, October 11, 13

Slide 24

Slide 24 text

(swap! my-atom ) Swaps current atom value by applying with to it. Friday, October 11, 13

Slide 25

Slide 25 text

(reset! my-atom ) Resets current atom value to . Friday, October 11, 13

Slide 26

Slide 26 text

Update Types • Coordinated/Uncoordinated • Synchronous/Asynchronous Friday, October 11, 13

Slide 27

Slide 27 text

STM • reference, not value • refs / agents / atoms / vars • transactional memory access yes, with retries • no user locks, no deadlocks • mutation through pure function • coordinated • readers can read value at any point in time Friday, October 11, 13

Slide 28

Slide 28 text

STM • guarantees of “clear” values for readers and writers • atomic changes • changes are guaranteed • dereferenced values won’t change over the time Friday, October 11, 13

Slide 29

Slide 29 text

STM • There are also Refs • synchronous, coordinated • manual transaction control • evaluated in `dosync` block • supports transactional mutations via `alter` • support commutative operations via `commute` Friday, October 11, 13

Slide 30

Slide 30 text

STM • and Agents • uncoordianted, asynchronous updates • use their own thread pool • `send` for fixed thread pool • `send-off` for growing thread pool Friday, October 11, 13

Slide 31

Slide 31 text

Futures future Friday, October 11, 13

Slide 32

Slide 32 text

(def ft (future (+ 1 2 3 4 5 6))) ;; 㱺 #'user/ft ft ;; 㱺 # @ft ;; 㱺 21 Friday, October 11, 13

Slide 33

Slide 33 text

(def ft (future (reduce + (range 0 10000)))) ;; 㱺 #'user/ft (realized? ft) ;; 㱺 true @ft ;; 㱺 49995000 Friday, October 11, 13

Slide 34

Slide 34 text

Futures • Work with java.util.concurrent.Future • Perform job in background, return control immediately • Dereferencing/get blocks • Dereferencing is possible with timeout Friday, October 11, 13

Slide 35

Slide 35 text

Locking locking Friday, October 11, 13

Slide 36

Slide 36 text

(let [l (java.util.ArrayList.)] (locking l (.add l 10)) l) ;; 㱺 # Friday, October 11, 13

Slide 37

Slide 37 text

Locking • Usually not required, because of immutable nature of DSs • May be needed in cases with heavy Java Interop Friday, October 11, 13

Slide 38

Slide 38 text

java.util.concurrent Friday, October 11, 13

Slide 39

Slide 39 text

Latches Friday, October 11, 13

Slide 40

Slide 40 text

(let [cnt (atom []) n 5 latch (java.util.concurrent.CountDownLatch. n)] (doseq [i (range 0 n)] (.start (Thread. (fn [] (swap! cnt conj i) (.countDown latch))))) (.await latch) @cnt) Friday, October 11, 13

Slide 41

Slide 41 text

Latches • Very useful for tests • Useful for understanding parallel execution flows Friday, October 11, 13

Slide 42

Slide 42 text

Atomic Vars Friday, October 11, 13

Slide 43

Slide 43 text

(let [l (AtomicLong.)] (dotimes [i 50] (.start (Thread. (fn [] (.incrementAndGet l))))) (.get l)) ;; 㱺 49 Friday, October 11, 13

Slide 44

Slide 44 text

Atomic Vars • Atomic values without arbitration • In majority of cases you can (should) use atoms Friday, October 11, 13