Clojure concurrency overview

2,269 views

Published on

Clojure, concurrency basics, atoms, vars, agents, refs.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,269
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
34
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Clojure concurrency overview

  1. 1. Agenda-Overview-Clojure features-Concurrent programming-Vars-Refs and STM approach-Atoms-Agents
  2. 2. OverviewRich 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/
  3. 3. What is Clojure?Clojure is a dynamic, LISP-like programming language that runs on the JVM
  4. 4. How does it look? Exactly! Like LISP
  5. 5. A form is a list where the first symbol in thelist has to be a special word that thecompiler can understand - usually the nameof a function
  6. 6. 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
  7. 7. 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
  8. 8. 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
  9. 9. Concurrent programming● Things are happening at the same time● Number of CPU is growing fast
  10. 10. Concurrent programming problemsVisibility problem ● Multiple threads use shared data ● 2 or more threads are trying to change the same data at the same time
  11. 11. Concurrent programming problemsBasic solution is ● locks ● synchronized access ● only one thread can have lock, others blocks ● But it requires additional efforts ○ thread-coordination ○ avoiding deadlocks
  12. 12. Concurrent programming problemsAccess 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
  13. 13. 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
  14. 14. But what ifwe really want change data in Clojure? This opportunity is also provided by the language! All hard work done for us.
  15. 15. Reference types● Vars● Refs● Atoms● Agents
  16. 16. 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
  17. 17. 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
  18. 18. 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
  19. 19. 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)
  20. 20. Refs lifecycle (def r (ref (1 2 3))) (deref r) (dosync .... if any other transaction (alter r commutes - this (fn [_] (10 9 8)) transaction is repeated ... ) Otherwise, thats ok and (deref r) programs continues execution
  21. 21. 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
  22. 22. 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)))))
  23. 23. 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"
  24. 24. 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
  25. 25. 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
  26. 26. 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
  27. 27. Q&A

×