As we can see, threading has the potential to be very difficult. We not only need to decide how our code can operate on multiple threads, or how we can make use of asynchronous operations, we also need to guarantee our data doesn't get corrupted.
With some easy-to-follow practices, we can decide when and how we can parallelize work in our applications. We now know which APIs are best to use when we want to use asynchronous operations, but we also know how we can go about ensuring our invariants.
There are many ways of making our code thread-safe and protecting our invariants. With a few useful practices, we can not only make our code thread-safe, but we don't need to make it really slow either.
In the next chapter, we'll look at similar parallelization topics, except spanning process boundaries: distributed applications. We'll look at ways of architecting distributed applications, as well as specific technologies that help communication of nodes within a distributed application. In...