concurrency-modelle auf der jvm auf der w-jax 3.11.2015
TRANSCRIPT
w-jax 2015
Concurrency-Modelle auf der JVM
Lutz Hühnken @lutzhuehnken
Provokante These: Java braucht ein neues Concurrency - Modell!
Warum ist Concurrency interessant?
Es ist ein relevantes Problem
Es ist ein nicht-triviales Problem
w-jax 2015 4
w-jax 2015 5
w-jax 2015 6
w-jax 2015 7
Threads
Threads
Problem 1: Effizienz
Problem 2: Programmiermodell
w-jax 2015 10
w-jax 2015 11
1 2 3 … 10.000
w-jax 2015 12
w-jax 2015 13
Source: John Rose, Java VM Architect, JFokus, Stockholm, February 2015
Reactive Slick
Warum ist asynchrone I/O so wichtig?
Threads als kleinste Einheit der Nebenläufigkeit
14
Wichtig: Dies ist eine Momentaufnahme, kein Ablauf
Reactive Slick
Warum ist asynchrone I/O so wichtig?
Threads als Vehikel für kleinere Einheiten
15
Wichtig: Dies ist eine Momentaufnahme, kein Ablauf
#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
Threads
Problem 1: Effizienz
Problem 2: Programmiermodell
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.
#codetalkshh
Einschub: Callback Hellfs.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
#codetalkshh
Man kann das schöner schreiben
• Futures / for-expression (Scala) • async / await
• Syntactic Sugar • Probleme bleiben
20
Was interessiert uns?
Zustand
Komposition
Integration
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
w-jax 2015
Fibersnew Fiber<V>() { @Override protected V run() throws SuspendExecution,
InterruptedException { // code hier }}.start();
23
w-jax 2015
Fibers
Vorteil: Imperative Programmierung, wie mit Threads
Nachteil: Imperative Programmierung, wie mit Threads
24
w-jax 2015
Fibersclass 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
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
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
w-jax 2015
Agenten
• Der Agent kapselt den Zustand
• Sende eine Funktion als Nachricht an den Agenten, diese wird asynchron ausgeführt
28
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
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
w-jax 2015
Clojure Channels
(def echo-chan (chan)) (go (println (<! echo-chan))) (>!! echo-chan "ketchup") ; => true ; => ketchup
31
w-jax 2015
Clojure Channels
(def echo-buffer (chan 2)) (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; => true (>!! echo-buffer "ketchup") ; blocks
32
w-jax 2015
Channels Zusammenfassung
• Sehr flexible Komposition • Nach außen Optionen für asynchrone und
synchrone APIs
33
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!"); } }
w-jax 2015
Event Bus (vert.x)
35
Image from Jonas Bandi @jbandi
w-jax 2015
Event Bus (vert.x) Zusammenfassung
• „Single Thread Illusion“ • Lose Kopplung • Hybrides Thread-Modell • Bonus: Verteilung
36
w-jax 2015
Aktoren (Akka)
37
w-jax 2015
Aktoren (Akka) II/V
38
w-jax 2015
Aktoren (Akka)
39
w-jax 2015
Aktoren (Akka)
40
w-jax 2015
Aktoren (Akka)
41
w-jax 2015
Aktoren (Akka)
42
w-jax 2015
Aktoren (Akka) Zusammenfassung
• „Single Thread Illusion“ • Messaging, incl. Routing etc. • Dispatcher • Bonus: Verteilung, Supervision
43
w-jax 2015 44
ProgrammiermodelleTasks (sub-thread level)
Asynchrones Messaging
Verteilung Supervision
Fibers✔
Channels (core.async) ✔ ✔
Event Bus (vert.x) ✔ ✔ ✔
Aktoren (Akka) ✔ ✔ ✔ ✔
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
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
w-jax 2015
• Concurrency ist interessant
• Threads sind passé, Alternativen sind vorhanden
• Wenn ihr euch nur eine Alternative anseht, empfehle ich Akka
47
Fazit
Vielen Dank
(Typesafe - Stand: 1. Stock)
Lutz Hühnken @lutzhuehnken