clojure concurrency overview
DESCRIPTION
Clojure, concurrency basics, atoms, vars, agents, refs.TRANSCRIPT
![Page 1: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/1.jpg)
![Page 2: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/2.jpg)
Agenda
-Overview-Clojure features-Concurrent programming-Vars-Refs and STM approach-Atoms-Agents
![Page 3: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/3.jpg)
Overview
Rich Hickeyhttps://twitter.com/#!/richhickey
-about 2.5 years working on Clojure-first public release at 2007-interview: http://www.simple-talk.com/opinion/geek-of-the-week/rich-hickey-geek-of-the-week/
![Page 4: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/4.jpg)
What is Clojure?
Clojure is a dynamic, LISP-like programming language that runs on the JVM
![Page 5: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/5.jpg)
How does it look? Exactly! Like LISP
![Page 6: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/6.jpg)
A form is a list where the first symbol in the list has to be a special word that the compiler can understand - usually the name of a function
![Page 7: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/7.jpg)
Clojure Features
● Functional○ Immutable, persistent data structures○ Functions are objects
● Lisp● Hosted on JVM
○ the same memory model○ garbage collector○ etc
● Supporting Concurrency ● Open source
![Page 8: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/8.jpg)
Clojure Features
● Dynamic development○ REPL (read-eval-print-loop), on-the-fly
compilation to JVM bytecode● Full set of immutable, extensible, read-only
data structures:○ lists○ maps○ sets○ vectors
● Macros
![Page 9: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/9.jpg)
Clojure Features
Java interop
● Call java-methods, access fields● Functions implement java.util.concurrent.
Callable (defn func (smthng)) ● Proxy interfaces/classes● Primitive types - int, long, byte, Char, String etc● Clojure data structures implement Collection, Iterable,
Comparable etc
![Page 10: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/10.jpg)
Concurrent programming
● Things are happening at the same time● Number of CPU is growing fast
![Page 11: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/11.jpg)
Concurrent programming problems
Visibility problem● Multiple threads use shared data● 2 or more threads are trying to
change the same data at the same time
![Page 12: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/12.jpg)
Concurrent programming problems
Basic solution is● locks● synchronized access● only one thread can have
lock, others blocks ● But it requires additional efforts
○ thread-coordination○ avoiding deadlocks
![Page 13: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/13.jpg)
Concurrent programming problems
Access problem● several threads are trying to
access and change the same shared data at the same time
● write/read at the same time● readers block readers
![Page 14: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/14.jpg)
Clojure way
● There is no any possibility to change data by direct access. All data structures are immutable, remember?
● Only read, if we add element - new data structure will be created.
● No locks● No access problems
![Page 15: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/15.jpg)
But what if we really want change
data in Clojure?This opportunity is also
provided by the language! All hard work done for us.
![Page 16: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/16.jpg)
Reference types
● Vars● Refs● Atoms● Agents
![Page 17: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/17.jpg)
Vars
● Reference to mutable storage location ● Dynamically rebound on a per-thread basis● Functions are vars, so they can be dynamically rebound too● Ensure safe use via thread-isolation
(def x 5) // root-binding(x) // 5....(binding [x 20] (+ x 1)) // 21 ....(x) // 5 again, not changed
![Page 18: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/18.jpg)
Changing Vars
(set! var-name new-value)● cannot change root-binding● works only in thread-local context (in "binding")
(def x 5) // root-binding(set! x 7) // exception will be thrown....(binding [x 20] (println (+ x 1)) // 21 (set! x 10) (+ x 5)) // 15....(x) // 5 again, not changed
![Page 19: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/19.jpg)
Refs
● Based on Software Transactional Memory (STM)● Change the value by applying a function to old value ● Refs can be changed within a transaction only ● Transactions will be retried automatically if conflict happens● To make changes code must be surrounded with (dosync
...)● All changes are atomic
![Page 20: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/20.jpg)
Refs
(def r (ref '(1 2 3))) (deref r) // list (1 2 3) (dosync // transaction begins .... (alter r // change ref! (fn [_] '(10 9 8)) ... ) // transaction ends (deref r) // list (10 9 8)
![Page 21: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/21.jpg)
Refs lifecycle
(def r (ref '(1 2 3))) (deref r) (dosync .... (alter r (fn [_] '(10 9 8)) ... ) (deref r)
if any other transaction commutes - this transaction is repeated
Otherwise, that's ok and programs continues execution
![Page 22: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/22.jpg)
Atoms
● Way to manage shared state synchronously�● Change the value by applying a function to old value● This is done in an atomic manner by function swap!�● Internally, swap! reads the current value, appliesthe
function to it, and attemprs to call compare-and-set! for this atom
![Page 23: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/23.jpg)
Atoms best practices by Rich Hickey
(defn memoize [f] (let [mem (atom {})] (fn [& args] (if-let [e (find @mem args)] (val e) (let [ret (apply f args)] (swap! mem assoc args ret) ret)))))
![Page 24: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/24.jpg)
Atoms best practices by Rich Hickey
(defn fib [n] (if (<= n 1) n (+ (fib (dec n)) (fib (- n 2))))) (time (fib 35))user=> "Elapsed time: 941.445 msecs" (def fib (memoize fib)) (time (fib 35)) user=> "Elapsed time: 0.044 msecs"
![Page 25: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/25.jpg)
Agents
● Asynchronous changing. They are not blocking main execution, return immediately
● Change the value by applying a function to old value● Agent action dispatches take the
form (send agent fn args*)● �If other actions try to change data - they will be added to
the queue
![Page 26: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/26.jpg)
Agents
(def a (agent 5)) // create agent(deref a) // 5
(send a (fn [old-val] (+ old-val 5)))(deref a) // may be 5, or may be 10(Thread/sleep 1000)(deref a) // 10
![Page 27: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/27.jpg)
Useful links
● https://groups.google.com/forum/#!forum/clojure ● http://clojure.org ● http://alexott.net/ru/clojure/index.html ● http://www.lisperati.com/clojure-spels/casting.html ● http://www.pluralsight-training.
net/microsoft/courses/TableOfContents?courseName=clojure-concurrency-tutorial
![Page 28: Clojure concurrency overview](https://reader034.vdocument.in/reader034/viewer/2022052505/5550f3cfb4c90501448b45d1/html5/thumbnails/28.jpg)
Q&A