Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Concurrency on the JVM

3,503 views

Published on

Published in: Technology
  • Be the first to comment

Concurrency on the JVM

  1. 1. <ul>Concurrency </ul><ul>Unleash your processor(s) Václav Pech </ul>
  2. 2. <ul>About me </ul><ul><li>Passionate programmer
  3. 3. Concurrency enthusiast
  4. 4. GPars @ Codehaus lead
  5. 5. Technology evangelist @ JetBrains
  6. 6. JetBrains Academy member </li></ul><ul>http://www.jroller.com/vaclav </ul><ul><ul><li>http://twitter.com/vaclav_pech </li></ul></ul>
  7. 7. <ul>The evil accumulator </ul><ul><li>int sum=0;
  8. 8. for(int i : collection) sum += i; </li></ul>
  9. 9. <ul>We’re quad core already </ul><ul>Beware: More cores to come shortly! </ul>
  10. 10. <ul>Stone age of parallel SW </ul><ul><li>Dead-locks
  11. 11. Live-locks
  12. 12. Race conditions
  13. 13. Starvation
  14. 14. Shared Mutable State </li></ul>
  15. 15. <ul>Lock and synchronize </ul><ul>Multithreaded programs today work mostly by accident! </ul>
  16. 16. <ul>Can we do better? </ul><ul>Map/Reduce </ul><ul>Fork/Join </ul><ul>Actors </ul><ul>STM </ul><ul>Dataflow </ul><ul>Agent </ul>
  17. 17. <ul>Asynchronous invocation </ul><ul>Future f = threadPool.submit (calculation); … System.out.println( “Result: “ + f.get()); </ul><ul>main </ul><ul>calculation </ul><ul>get() </ul>
  18. 18. <ul>Collections (GPars) </ul><ul>images. eachParallel {it.process()} documents. sumParallel () candidates. maxParallel {it.salary}.marry() </ul>
  19. 19. <ul>Parallel Arrays (jsr-166y) </ul><ul>ParallelArray namesOfWomen = people .withFilter( aWoman ).withMapping( retrieveName ).all(); Ops.Predicate aWoman = new Ops.Predicate() { public boolean op(Person friend) {return !friend.isMale();} }; Ops.Op retrieveName = new Ops.Op() { public Object op(Person friend) {return friend.getName();} }; </ul>
  20. 20. <ul>Fork/Join </ul><ul><li>Solve hierarchical problems </li></ul><ul><ul><ul><li>Divide and conquer </li></ul><li>Merge sort, Quick sort
  21. 21. Tree traversal
  22. 22. File scan / search
  23. 23. … </li></ul></ul><ul>[a, b, c, d, e, f, g, h] </ul><ul>[a, b, c, d] </ul><ul>[e, f, g, h] </ul><ul>[a, b] </ul><ul>[c, d] </ul><ul>[e, f] </ul><ul>[g, h] </ul>
  24. 24. <ul>Fork/Join (GPars) </ul><ul>runForkJoin(new File( “./src” )) {currentDir -> long count = 0; currentDir.eachFile { if (it.isDirectory()) { println &quot;Forking a thread for $it&quot; forkOffChild it } else { count++ } } return count + childrenResults .sum(0) } </ul><ul>Waits for children without blocking the thread! </ul>
  25. 25. <ul>Dataflow Concurrency </ul><ul><li>No race-conditions
  26. 26. No live-locks
  27. 27. Deterministic deadlocks </li></ul><ul><ul><li>Completely deterministic programs </li></ul></ul><ul>BEAUTIFUL code </ul><ul><ul><li>(Jonas Bonér) </li></ul></ul>
  28. 28. <ul>Dataflow Variables / Promises </ul><ul>main </ul><ul>task2 </ul><ul>task3 </ul><ul>x </ul><ul>y </ul><ul>z </ul><ul>task1 </ul>
  29. 29. <ul>DataFlows (GPars) </ul><ul>def df = new DataFlows () task { df .z = df .x + df .y } task { df .x = 10 } task { df .y = 5 } assert 15 == df .z </ul>
  30. 30. <ul>Promises (Clojure) </ul><ul>(def x ( promise )) (def y (…))(def z (…)) ( future ( deliver z (+ @x @y))) ( future ( deliver x 10)) ( future ( deliver y 5)) (println @z) </ul>
  31. 31. Milestone <ul><li>Asynchronous background tasks
  32. 32. Parallel collection processing
  33. 33. Fork/Join
  34. 34. Dataflow variables/streams </li></ul>
  35. 35. Message Passing Communicating Sequential Processes (CSP) Dataflow Operators Actors
  36. 36. CSP Stands for Communicating Sequential Processes Highly deterministic Composable
  37. 37. <ul>Dataflow Operators (GPars) </ul><ul>operator(inputs: [stocksStream], outputs: [pricedStocks]) { stock -> def price = getClosing( stock , 2008) bindOutput(0, [stock: stock , price: price ]) } </ul><ul>* </ul><ul>+ </ul><ul><> </ul>
  38. 38. <ul>Actors </ul><ul><li>Isolated
  39. 39. Communicating </li></ul><ul><ul><li>Immutable messages </li></ul></ul><ul><li>Active </li></ul><ul><ul><li>Pooled shared threads </li></ul></ul><ul><li>Activities </li></ul><ul><ul><li>Create a new actor
  40. 40. Send a message
  41. 41. Receive a message </li></ul></ul><ul>Actor </ul><ul>Actor </ul><ul>Actor </ul><ul>Actor </ul><ul>Actor </ul><ul>Actor </ul><ul>Actor </ul><ul>T </ul><ul>T </ul><ul>T </ul><ul>Thread pool </ul>
  42. 42. <ul>Actors use </ul><ul>Gate Keeper </ul><ul>Form </ul><ul>HTTP </ul><ul>Finger Prints </ul><ul>Address Check </ul><ul>Email Check </ul><ul>Process </ul><ul>Fraud Detect </ul><ul>Response </ul><ul>SOAP </ul><ul>SMTP </ul>
  43. 43. <ul>Actors patterns </ul><ul>Enricher Router Translator Endpoint Splitter Agregator Filter Resequencer Checker </ul>
  44. 44. <ul>Creating Actors (GPars) </ul><ul>class MyActor extends AbstractPooledActor { void act() { def buddy = new YourActor().start() buddy << ‘Hi man, how’re things?’ def response = receive () } } </ul>
  45. 45. <ul>Creating Actors (Scala) </ul><ul>val me = actor { loop { react { <li>case w:Work=>reply “I don't work so early”
  46. 46. case b:Breakfast=>
  47. 47. b.eat
  48. 48. react { </li></ul><ul><li>case w:Work=>reply “OK, time to work” ; w.do </li></ul><ul><li>case l:Lunch=>
  49. 49. ...
  50. 50. } } } }
  51. 51. me ! cake </li></ul>
  52. 52. <ul>Continuation Style </ul><ul>loop { … react { … react { /*schedule the block; throw CONTINUE*/ … } //Never reached } //Never reached } //Never reached </ul>
  53. 53. <ul>Creating Actors (Akka - Scala) </ul><ul>class MyActor extends Actor { def receive = { case &quot;Hello&quot; => reply(&quot;World&quot;) case Register(user, sender) => val registrationCode = register(user) sender ! SuccessfulRegistration(registrationCode) case _ => throw new RuntimeException(&quot;unknown message&quot;) } } Example form http://doc.akkasource.org/actors </ul>
  54. 54. <ul>Creating Actors (Jetlang) </ul><ul>Fiber fiber = new ThreadFiber(); fiber .start(); Channel<String> channel = new MemoryChannel<String>(); Callback<String> runnable = new Callback<String>() { public void onMessage (String msg) {     log(msg.toUpperCase());     } }; channel.subscribe( fiber , runnable ); channel.publish( &quot;hello&quot; ); Based on sample code from http://code.google.com/p/jetlang/ </ul>
  55. 55. <ul>Java actor frameworks </ul><ul>Jetlang Kilim ActorFoundry Actorom Akka … </ul>
  56. 56. Shared Mutable State Misused in about 95% of current usages For the remaining 5% use <ul><li>Agents
  57. 57. Software Transactional Memory </li></ul>
  58. 58. <ul>Agent </ul><ul><li>Lock Shared Mutable State in a Safe </li></ul><ul>Alter the State </ul><ul>Alter the State </ul>
  59. 59. <ul>Agent inside </ul><ul>Double </ul><ul>Increment </ul><ul>Add 25 </ul><ul>Message Queue </ul><ul>36 </ul><ul>thread </ul>
  60. 60. <ul>Agent (Clojure) </ul><ul>(defn increment [c] (+ c 1)) (defn decrement [c] (- c 1)) (defn add [c delta] (+ c delta)) (def a ( agent 0)) (send a increment ) | (send a decrement ) | (send a add 25) | … (await a) (println @a) </ul>
  61. 61. <ul>STM (Clojure) </ul><ul>(defstruct person :name :gender :age) (def people (ref #{} )) ( dosync ( alter people conj (struct person &quot;Joe&quot; &quot;male&quot; 39)) ( alter people conj (struct person &quot;Alice&quot; &quot;female&quot; 27)) ( alter people conj (struct person &quot;Dave&quot; &quot;male&quot; 41)) ) </ul>
  62. 62. <ul>STM (Akka - Scala) </ul><ul>atomic { .. // do something within a transaction } atomic (maxNrOfRetries) { .. } atomicReadOnly { .. } atomically { .. // try to do something } orElse { .. // if tx clash; try do do something else } Sample taken from Akka documentation - http://doc.akkasource.org/stm </ul>
  63. 63. Multiverse @ TransactionalObject public class Account{ private int balance; public Account(int initialBalance){...} public int getBalance(){...} public setBalance(int newBalance){...} }
  64. 64. <ul>Persistent Data Structures </ul><ul>Illustration taken from Rich Hickey's presentation. Copyright Rich Hickey 2009 </ul>
  65. 65. <ul>No more threads and locks </ul><ul>images. eachParallel { //concurrency agnostic code here } def myActor = actor { //concurrency agnostic code here } (dosync /*concurrency agnostic code here*/) … </ul>
  66. 66. <ul>Summary </ul><ul><li>Parallelism is not hard, multi-threading is
  67. 67. Jon Kerridge, Napier University </li></ul>
  68. 68. <ul>Tips </ul><ul><li>Java </li></ul><ul><ul><li>JSR-166y - Fork/Join, Parallel Arrays
  69. 69. Multiverse, Jetlang, Kilim, Actorom, ActorFoundry </li></ul></ul><ul><li>Clojure </li></ul><ul><ul><li>STM, Atoms, Agents, Promises </li></ul></ul><ul><li>Scala </li></ul><ul><ul><li>Actors, Akka, ScalaAgent </li></ul></ul><ul><li>Groovy </li></ul><ul><ul><li>GPars – actors, agent, dataflow, fork/join, map/reduce </li></ul></ul>
  70. 70. <ul><li>Questions?
  71. 71. Find more at: </li><ul><li>http://gpars.codehaus.org
  72. 72. http://www.jroller.com/vaclav
  73. 73. http://twitter.com/vaclav_pech </li></ul></ul>

×