JVM Concurreny Models at code.talks, Hamburg, 30.9.2015

991 Aufrufe

Veröffentlicht am

Neue Concurrency-Modelle auf der JVM - über Fibres, Agents, Verticles und Actors

Nebenläufigkeit hieß bisher in Java: java.util.concurrent und Threads. Threads wurden ursprünglich als „lightweight processes“ konzipiert: Neue Prozesse zu starten, um nebenläufige Operationen zu implementieren, bedeutete zuviel Overhead, und hat das Problem der Kommunikation zwischen den Prozessen aufgeworfen. Threads sollten "leicht" sein und beide Nachteile beseitigen: Weniger Resourcen für die Erzeugung und Scheduling, und gemeinsame Speichernutzung. Allerdings stößt das Modell heute an seine Grenzen. Der Resourcenverbrauch ist immer noch zu groß, und der gemeinsame Speicher ist mehr Problem als Lösung: Race Conditions, Locks, Contention. Um Oracles Java VM-Architekten John Rose zu zitieren: "Threads sind passé". Wir wollen verschiedene Ansätze betrachten, Nebenläufigkeit unterhalb des Thread-Levels umzusetzen, und ihre Vor- und Nachteile beleuchten. Vorgestellt werden Quasar Fibers, Clojure Agents, vert.x Verticles und Akka Actors. Der Vortrag richtet sich an alle, die auf der Java-Platform entwickeln, in Java, Scala oder Clojure.

Veröffentlicht in: Software
0 Kommentare
1 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
991
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
83
Aktionen
Geteilt
0
Downloads
8
Kommentare
0
Gefällt mir
1
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

JVM Concurreny Models at code.talks, Hamburg, 30.9.2015

  1. 1. #codetalkshh New Concurrency Models on the JVM Lutz Hühnken http://www.huehnken.de | @lutzhuehnken
  2. 2. #codetalkshh Warum ist Concurrency überhaupt interessant? 2
  3. 3. #codetalkshh Hardware ist parallel. 3
  4. 4. #codetalkshh Wir finden sequentiell einfach. 4
  5. 5. #codetalkshh 5
  6. 6. #codetalkshh 6
  7. 7. #codetalkshh 7
  8. 8. #codetalkshh 8
  9. 9. #codetalkshh Wie sieht es denn heute aus? Threads. 9
  10. 10. #codetalkshh Problem 1: Effizienz 10
  11. 11. #codetalkshh 11
  12. 12. #codetalkshh 12 1 2 3 … 10.000
  13. 13. #codetalkshh 13 Source: John Rose, Java VM Architect, JFokus, Stockholm, February 2015
  14. 14. #codetalkshh Lösung Effizienz: • Sub-Thread-Level Concurrency • Asynchrone I/O
 • Das ist allen den folgenden Ansätzen gemeinsam!
 • Das ist allen „Reactive Systems“ gemeinsam! 14
  15. 15. #codetalkshh Problem 2: Programmiermodell 15
  16. 16. #codetalkshh 16 They discard the most essential and appealing properties of sequential computation: understandability, predictability, and determinism. Threads, as a model of computation, are wildly nondeterministic, and the job of the programmer becomes one of pruning that nondeterminism.
  17. 17. #codetalkshh Was interessiert uns denn? Zustand Komposition Interoperation 17
  18. 18. #codetalkshh 18 Green Threads (User Mode Threads, Fibers) Quasar Agenten Clojure Communicating Sequential Processes (CSP) Clojure Event Bus vert.x Aktoren Akka Programmiermodelle
  19. 19. #codetalkshh Fibers new Fiber<V>() { @Override protected V run() throws SuspendExecution, InterruptedException { // code hier } }.start(); 19
  20. 20. #codetalkshh Fibers Vorteil: Imperative Programmierung, wie mit Threads Nachteil: Imperative Programmierung, wie mit Threads 20
  21. 21. Reactive Slick Warum ist asynchrone I/O so wichtig? Threads als kleinste Einheit der Nebenläufigkeit 21 Wichtig: Dies ist eine Momentaufnahme, kein Ablauf
  22. 22. Reactive Slick Warum ist asynchrone I/O so wichtig? Threads als Vehikel für kleinere Einheiten (z.B. Fibers) 22 Wichtig: Dies ist eine Momentaufnahme, kein Ablauf
  23. 23. #codetalkshh Einschub: Callback Hell fs.readdir(source, function(err, files) { if (err) { console.log('Error finding files: ' + err) } else { files.forEach(function(filename, fileIndex) { console.log(filename) gm(source + filename).size(function(err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = (values.width / values.height) widths.forEach(function(width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write(destination + 'w' + width + '_' + filename, function(err) { if (err) console.log('Error writing file: ' + err) }) }.bind(this)) } }) }) } }) 23
  24. 24. #codetalkshh Callback Hell Alternativen • Channels (sehen wir noch) • Events oder Messages (sehen wir noch) • Lesbare Syntax für „onComplete“ (z.B. Scala flatMap / for expression) 24
  25. 25. #codetalkshh Fibers class FooAsync extends FiberAsync<String, FooException> implements FooCompletion { @Override public void success(String result) { asyncCompleted(result); } @Override public void failure(FooException exception) { asyncFailed(exception); } } wird zu String op() { new FooAsync() { protected void requestAsync() { Foo.asyncOp(this); } }.run(); } 25
  26. 26. #codetalkshh Fibers •Effizienz ja •Programmiermodell unverändert •Aber: Eine Menge interessanter Tricks (Instrumentation, Continuations, Thread Interop) •Low-level Grundlage für andere Konstrukte •Drop-In Ersatz für Threads 26
  27. 27. #codetalkshh Agenten (def x (agent 0)) (defn increment [c n] (+ c n)) (send x increment 5) ; @x -> 5 (send x increment 10) ; @x -> 15 27
  28. 28. #codetalkshh Agenten • Der Agent kapselt den Zustand
 • Sende eine Funktion als Nachricht an den Agenten, diese wird asynchron ausgeführt 28
  29. 29. #codetalkshh Agenten • Attraktivität: Funktionale Programmierung! (Unveränderliche Werte als Normalfall, veränderlicher Zustand als Ausnahme)
 • Keine Lösung für Komposition, daher ☞ Channels 29
  30. 30. #codetalkshh Clojure Channels (def echo-chan (chan)) (go (println (<! echo-chan))) (>!! echo-chan "ketchup") ; => true ; => ketchup 30
  31. 31. #codetalkshh Clojure Channels (def echo-buffer (chan 2)) (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; blocks 31
  32. 32. #codetalkshh Channels • Sehr flexible Komposition • Implementieren Communicating Sequential Processes (Tony Hoare 1978, https:// en.wikipedia.org/wiki/ Communicating_sequential_processes) 32
  33. 33. #codetalkshh Event Bus (vert.x) 33 public class Receiver extends AbstractVerticle { @Override public void start() throws Exception { EventBus eb = vertx.eventBus(); eb.consumer("ping-address", message -> { System.out.println("Received message: " + message.body()); // Now send back reply message.reply("pong!"); }); System.out.println("Receiver ready!"); } }
  34. 34. #codetalkshh Event Bus (vert.x) 34 Image from Jonas Bandi @jbandi
  35. 35. #codetalkshh Event Bus (vert.x) • „Single Thread Illusion“ • Lose Kopplung • Hybrides Thread-Modell • Bonus: Verteilung 35
  36. 36. #codetalkshh Aktoren (Akka) 36
  37. 37. #codetalkshh Aktoren (Akka) 37
  38. 38. #codetalkshh Aktoren (Akka) 38
  39. 39. #codetalkshh Aktoren (Akka) 39
  40. 40. #codetalkshh Aktoren (Akka) 40
  41. 41. #codetalkshh Aktoren (Akka) 41
  42. 42. #codetalkshh Aktoren (Akka) • „Single Thread Illusion“ • Messaging, incl. Routing etc. • Dispatcher • Bonus: Verteilung, Supervision 42
  43. 43. #codetalkshh 43 Green Threads (User Mode Threads, Fibers) Quasar Agenten Clojure Agents Communicating Sequential Processes (CSP) Clojure Channels Event Bus vert.x Aktoren Akka Programmiermodelle
  44. 44. #codetalkshh • Quasar hat auch eine Implementierung von Channels, und sogar Aktoren
 • Mit Akka kann man auch einen Event Bus implementieren, und auch Agenten
 • Es gibt eine Welt außerhalb der JVM (Go Channels, Erlang…)
 • … 44 Der Vollständigkeit halber
  45. 45. #codetalkshh • Concurrency ist interessant
 • Threads sind passé, Alternativen sind vorhanden
 • Wenn ihr euch nur eine Alternative anseht, empfehle ich Akka 45 Fazit
  46. 46. Vielen Dank Nicht vergessen: Bewertung abgeben (in der App) Lutz Hühnken http://www.huehnken.de | @lutzhuehnken

×