The author presents seven different approaches to concurrency and parallelism, in four different programming languages (Java, Clojure, Elixir, C / OpenCL) and weighs them one agains the other.
The book starts by discussing the most obvious approach - explicit thread and lock management, and later on shows how alternative models manage the complexity and safety issues of this approach. Clojure is presented as an example of a functional language which is immutable by default (through the use of efficient persistent data structures), demonstrating its concurrency abilities through threads (wrapped in futures and promises for convenience) and managing explicit state with atomics and STM. Elixir (a dialect of Erlang) is shown to demonstrate distributed, fault-tolerant programming. Then Clojure again for a presentation of CSP (the techique that's now back in vogue thanks to Go). It finishes off with OpenCL - a chapter that differs from the others since it discusses parallelism at a far more detailed granularity; finally, it presents "Lambda Architecture" - a collection of libraries on top of Java to implement map-reduces and variations thereof.
I liked the book overall, though I do have a bit of criticism:
- The code samples are not always clear, and sometimes too short. I feel the book could be better if it spent an extra 100 pages on showing more of the code and explaining it.
- Related to the above, the author is very eager to use libraries for fairly simple tasks instead of reinventing the wheel. Except that when you're learning about a new programming paradigm, in a new programming language, spending an extra 20 lines of text to define a function instead of importing it is well worth the effort, IMHO.
- Some of the Clojure samples for using CSP are outdated, even though the book is from 2014. Functions used in the book (such as map<) are now marked deprecated in Clojure.
Some key take-aways:
- Java has a very impressive array of built-in tools for concurrent and parallel programming. Thread pools, a fork-join framework, varieties of concurrent queues, you name it.
- Clojure! The book helped me (re-)discover this language, and I'm very thankful. A modern, fully-featured Lisp with a thriving, friendly community and tons of interesting ideas - what a gem. And it implements a very feature-full and well-designed form of CSP as a library - Lisp's macro magic in its best. I will definitely blog more about this in the future.
- Erlang/Elixir left me unimpressed. It seems like the biggest advantage of these languages is in actor frameworks like OTP , which could be implemented as a library in any modern language (JVM-based languages have Akka, for example). Even though actors look very interesting and certainly have useful semantics and ideas in them, the language(s) they come with are quirky and I don't know if I wanted a new language just for distributing my application.