Here are the key things to know about threads:
* Threads are for expressing asynchronous work. The point of being asynchronous is to let the units of independent work in the application all run at their own speeds and better tolerate each other’s latency.
* Threads are a low-level tool. Threads are just „sequential processes that share memory,“ and that kind of freewheeling anything-goes model doesn’t provide any abstraction or guard rails to make good practices easy and bad practices hard. As aptly criticized by Edward Lee in his paper „The Problem with Threads“ , threads let you do anything, and do it nondeterministically by default.
* „Up-level“ them by replacing shared data with asynchronous messages. As much as possible, prefer to keep each thread’s data isolated (unshared), and let threads instead communicate via asynchronous messages that pass copies of data. This best practice inherently encourages writing threads that are event-driven message processing loops, which gives inherent structure and synchronization and also improves determinism: