I grew up with a fear of Java
Threads. It was a time when Java and C# were the only “serious” programming languages to be used to write enterprise software. This was especially true in India, which to date remains a laggard in terms of technology adoption. The concept of Threads was hard enough for a budding programmer. And to make matters worse, the Thread API was far from being intuitive. Concurrency, deadlocks, semaphores, and synchronization were topics that were thrown around as stone pelters throw stones on anyone approaching their territory.
Reading the chapter on Concurrency in the book The Pragmatic Programmer triggered this comparison in my head. Having worked on professional software for over 12 years in several different languages, async code now feels intuitive. Back then, it was hard. Threads were hard. Not only would I skip reasoning about potential concurrency issues in my software, I would also leave out without flinching any discussion about concurrency or threads in reference material. Surely threads were designed to be used in “very complex” applications, something that I would not be doing until my late thirties. Hah!
It’s only now that I realize concurrency is unavoidable—it’s implicitly baked into so many daily problems that not thinking about concurrency means knowingly or unknowingly creating software that would not scale to survive the harshness of the real world.
So, here I am writing a note to my younger self:
It’s useful to think of threads simply in terms of tools that provide the ability to execute pieces of code asynchronously. Before
Future , the only way to run async code in Java was to use a
Thread. In short, a thread is just Java async code.
Node.js made it super-easy to run async code via callbacks, so much so that it became a preferred standard when writing I/O heavy code. So, programmers who would not write async or non-blocking code in Java due to the fear of threads could easily do so in Node.