Despite most programming tasks today usually reasoning about concurrency at a higher abstraction level, such as transactions or managed thread pools, low-level concurrent programming maneuvers that fiddle with atomic instructions and locks never go out of fashion. In my humble opinion, the challenge of designing and debugging those programs perfectly resembles that of solving a mathematical puzzle: the description of the problem is deceivingly simple as most of them are trivial if done sequentially, but the solution that enables concurrency is often subtle, and worst, reasoning about why a solution works (or does not work) can be terribly complicated.