Go Concurrency in der Praxis (Teil 1): Futures
tarent Blog

Go Concurrency in der Praxis (Teil 1): Futures

13.06.2019 Posted 3 Monaten ago Dino Omanovic

Parallelität, Asynchronität, Concurrency, Multithreading: diese Themen sind häufig kompliziert und erfordern einen anderen Denkprozess. In der Programmiersprache Go haben wir einfache Konstrukte, um solche Herausforderungen zu lösen. In dieser Serie werde ich jeweils anhand eines praktischen Beispiels zeigen, wie Go uns ermöglicht, komplexe Patterns mit einfachen Tools umzusetzen.

Wir beginnen mit Futures. Was sind Futures? In der Programmierung gibt es häufig Prozesse, die eine Weile dauern. Damit wir erstmal weiterarbeiten können, nutzen wir einen Platzhalter für ein zukünftiges Ergebnis. Erst wenn wir das Ergebnis wirklich brauchen, warten wir dann darauf. Bestenfalls haben wir die Zeit gut genutzt und das Ergebnis ist schon da, wenn wir es brauchen.

Bekannt sind Futures beispielsweise aus Java. Dort erzeugt man einen Executor (z.B. ein ThreadPool), welcher ein Callable ausführt und dessen zukünftiges Ergebnis zurückgibt. Hier einmal als Code:

Go Concurrency in der Praxis

In Go machen wir das alles ein bisschen anders. Anstatt solche Patterns mit einem neuen Sprachkonstrukt “Future” umzusetzen, nutzen wir bestehende Bestandteile der Sprache. So können Patterns anhand ihrer Logik verstanden werden und wir können diese verstehen, auch wenn wir nur Go beherrschen, aber uns das Pattern unbekannt ist.

Goroutinen & Channels

In Go gibt es 2 Sprachfeatures, um die komplizierten Anforderungen zu lösen, die man für Asynchronität, Concurrency, Parallelität etc. braucht. Goroutinen & Channels.

Goroutinen sind “Green Threads”. Sie bilden eine Abstraktion über Threads und sind sehr leichtgewichtig. Wir müssen uns nicht mehr mit Threads herumschlagen, sondern können einfach “go” schreiben. Und zwar im wahrsten Sinne des Wortes:

Go Concurrency in der Praxis

Wir müssen uns keine Gedanken mehr machen, diese Funktion wird nun asynchron ausgeführt. Go kümmert sich für uns um das Scheduling.

Channels sind eine Möglichkeit, Werte zwischen und innerhalb von Goroutinen zu teilen. Anstatt von mehreren Goroutinen aus auf einen Wert zuzugreifen, kommunizieren diese über Kanäle. Channels sind typisiert und können auch einen Puffer haben für mehrere Werte.

Go Concurrency in der Praxis

In dem Fall haben wir Platz für einen Eintrag, sodass jemand, der schreibt, einfach weiterarbeiten kann und nicht darauf warten muss, dass seine Nachricht gelesen wird.

Diese beiden Bestandteile reichen, um das Future-Pattern nutzen zu können. Hier einmal das obige Beispiel in Go, ganz ohne ThreadPool:

Go Concurrency in der Praxis

Hier kann man sich das ganze auch live anschauen: https://play.golang.org/p/2IfIpDSLIuK

Hier gehts zum Fortbildungsangebot tarent Academy: Microservices mit Go

Dino Omanovic, Softwarearchitekt, Product Owner & Academy-Trainer für Go bei tarent