Slide 1

Slide 1 text

w-jax 2015 Concurrency-Modelle auf der JVM Lutz Hühnken @lutzhuehnken

Slide 2

Slide 2 text

Provokante These: Java braucht ein neues Concurrency - Modell!

Slide 3

Slide 3 text

Warum ist Concurrency interessant? Es ist ein relevantes Problem Es ist ein nicht-triviales Problem

Slide 4

Slide 4 text

w-jax 2015 4

Slide 5

Slide 5 text

w-jax 2015 5

Slide 6

Slide 6 text

w-jax 2015 6

Slide 7

Slide 7 text

w-jax 2015 7

Slide 8

Slide 8 text

Threads

Slide 9

Slide 9 text

Threads Problem 1: Effizienz Problem 2: Programmiermodell

Slide 10

Slide 10 text

w-jax 2015 10

Slide 11

Slide 11 text

w-jax 2015 11 1 2 3 … 10.000

Slide 12

Slide 12 text

w-jax 2015 12

Slide 13

Slide 13 text

w-jax 2015 13 Source: John Rose, Java VM Architect, JFokus, Stockholm, February 2015

Slide 14

Slide 14 text

Reactive Slick Warum ist asynchrone I/O so wichtig? Threads als kleinste Einheit der Nebenläufigkeit 14 Wichtig: Dies ist eine Momentaufnahme, kein Ablauf

Slide 15

Slide 15 text

Reactive Slick Warum ist asynchrone I/O so wichtig? Threads als Vehikel für kleinere Einheiten 15 Wichtig: Dies ist eine Momentaufnahme, kein Ablauf

Slide 16

Slide 16 text

#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! 16

Slide 17

Slide 17 text

Threads Problem 1: Effizienz Problem 2: Programmiermodell

Slide 18

Slide 18 text

w-jax 2015 18 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.

Slide 19

Slide 19 text

#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)) } }) }) } }) 19

Slide 20

Slide 20 text

#codetalkshh Man kann das schöner schreiben • Futures / for-expression (Scala) • async / await
 • Syntactic Sugar • Probleme bleiben 20

Slide 21

Slide 21 text

Was interessiert uns? Zustand Komposition Integration

Slide 22

Slide 22 text

w-jax 2015 22 Green Threads (User Mode Threads, Fibers, IOC Threads, Coroutines) Quasar Fibers Agenten Clojure Agents Communicating Sequential Processes (CSP) Clojure Channels Event Bus vert.x Aktoren Akka Programmiermodelle

Slide 23

Slide 23 text

w-jax 2015 Fibers new Fiber() { @Override protected V run() throws SuspendExecution, InterruptedException { // code hier } }.start(); 23

Slide 24

Slide 24 text

w-jax 2015 Fibers Vorteil: Imperative Programmierung, wie mit Threads Nachteil: Imperative Programmierung, wie mit Threads 24

Slide 25

Slide 25 text

w-jax 2015 Fibers class FooAsync extends FiberAsync 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

Slide 26

Slide 26 text

w-jax 2015 Fibers Zusammenfassung •Effizienz ja •Programmiermodell unverändert •Aber: Eine Menge interessanter Tricks (Instrumentation, Continuations, Thread Interop) •Drop-In Ersatz für Threads 26

Slide 27

Slide 27 text

w-jax 2015 Agenten (def x (agent 0)) (defn increment [c n] (+ c n)) (send x increment 5) ; @x -> 5 (send x increment 10) ; @x -> 15 27

Slide 28

Slide 28 text

w-jax 2015 Agenten • Der Agent kapselt den Zustand
 • Sende eine Funktion als Nachricht an den Agenten, diese wird asynchron ausgeführt 28

Slide 29

Slide 29 text

w-jax 2015 Agenten • Attraktivität: Funktionale Programmierung! (Unveränderliche Werte als Normalfall, veränderlicher Zustand als Ausnahme)
 • Keine Lösung für Komposition, daher ‛ Channels 29

Slide 30

Slide 30 text

w-jax 2015 Channels • Implementieren Communicating Sequential Processes (Tony Hoare 1978, https:// en.wikipedia.org/wiki/ Communicating_sequential_processes) • Sehr populär in der Go - Welt 30

Slide 31

Slide 31 text

w-jax 2015 Clojure Channels (def echo-chan (chan)) (go (println (!! echo-chan "ketchup") ; => true ; => ketchup 31

Slide 32

Slide 32 text

w-jax 2015 Clojure Channels (def echo-buffer (chan 2)) (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; blocks 32

Slide 33

Slide 33 text

w-jax 2015 Channels Zusammenfassung • Sehr flexible Komposition • Nach außen Optionen für asynchrone und synchrone APIs 33

Slide 34

Slide 34 text

w-jax 2015 Event Bus (vert.x) 34 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!"); } }

Slide 35

Slide 35 text

w-jax 2015 Event Bus (vert.x) 35 Image from Jonas Bandi @jbandi

Slide 36

Slide 36 text

w-jax 2015 Event Bus (vert.x) Zusammenfassung • „Single Thread Illusion“ • Lose Kopplung • Hybrides Thread-Modell • Bonus: Verteilung 36

Slide 37

Slide 37 text

w-jax 2015 Aktoren (Akka) 37

Slide 38

Slide 38 text

w-jax 2015 Aktoren (Akka) II/V 38

Slide 39

Slide 39 text

w-jax 2015 Aktoren (Akka) 39

Slide 40

Slide 40 text

w-jax 2015 Aktoren (Akka) 40

Slide 41

Slide 41 text

w-jax 2015 Aktoren (Akka) 41

Slide 42

Slide 42 text

w-jax 2015 Aktoren (Akka) 42

Slide 43

Slide 43 text

w-jax 2015 Aktoren (Akka) Zusammenfassung • „Single Thread Illusion“ • Messaging, incl. Routing etc. • Dispatcher • Bonus: Verteilung, Supervision 43

Slide 44

Slide 44 text

w-jax 2015 44 Programmiermodelle Tasks (sub- thread level) Asynchrones Messaging Verteilung Supervision Fibers ✔ Channels (core.async) ✔ ✔ Event Bus (vert.x) ✔ ✔ ✔ Aktoren (Akka) ✔ ✔ ✔ ✔

Slide 45

Slide 45 text

w-jax 2015 • Nicht geeignet: Code mit Blocking I/O • Auch nicht geeignet: reine CPU Last • Es geht nicht um isolierte Performance, sondern Scalability
 45 Achtung bei Benchmarks

Slide 46

Slide 46 text

w-jax 2015 • 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…)
 • … 46 Der Vollständigkeit halber

Slide 47

Slide 47 text

w-jax 2015 • Concurrency ist interessant
 • Threads sind passé, Alternativen sind vorhanden
 • Wenn ihr euch nur eine Alternative anseht, empfehle ich Akka 47 Fazit

Slide 48

Slide 48 text

Vielen Dank (Typesafe - Stand: 1. Stock) Lutz Hühnken @lutzhuehnken