Understanding Multithreading in Programming

When I first started programming, I had a very simple mental model: 𝗦𝗮𝗺𝗲 𝗶𝗻𝗽𝘂𝘁 → 𝘀𝗮𝗺𝗲 𝗼𝘂𝘁𝗽𝘂𝘁. It felt almost like math. ⁉️ So I couldn’t understand how a program could sometimes 𝘣𝘦𝘩𝘢𝘷𝘦 𝘥𝘪𝘧𝘧𝘦𝘳𝘦𝘯𝘵𝘭𝘺 𝘸𝘪𝘵𝘩 𝘵𝘩𝘦 𝘦𝘹𝘢𝘤𝘵 𝘴𝘢𝘮𝘦 𝘥𝘢𝘵𝘢. Then I ran into multithreading. And I realized that in concurrent systems, 𝘵𝘪𝘮𝘦 𝘣𝘦𝘤𝘰𝘮𝘦𝘴 𝘱𝘢𝘳𝘵 𝘰𝘧 𝘵𝘩𝘦 𝘪𝘯𝘱𝘶𝘵. Two threads executing the same code can produce different results depending on timing. Not because the logic is wrong but because execution order isn’t guaranteed. ❌ 𝘊𝘰𝘳𝘳𝘦𝘤𝘵-𝘭𝘰𝘰𝘬𝘪𝘯𝘨 𝘤𝘰𝘥𝘦 𝘥𝘰𝘦𝘴𝘯’𝘵 𝘢𝘭𝘸𝘢𝘺𝘴 𝘮𝘦𝘢𝘯 𝘤𝘰𝘳𝘳𝘦𝘤𝘵 𝘣𝘦𝘩𝘢𝘷𝘪𝘰𝘳. 𝗧𝗵𝗶𝘀 𝗶𝘀 𝘁𝗵𝗲 𝗲𝘅𝗮𝗺𝗽𝗹𝗲 𝘄𝗵𝗲𝗿𝗲 𝗲𝘅𝗽𝗲𝗿𝗶𝗲𝗻𝗰𝗲 𝗰𝗼𝗺𝗲𝘀 𝗶𝗻 For example, something as simple as: 𝗰𝗼𝘂𝗻𝘁𝗲𝗿++; isn’t atomic. 𝗜𝘁’𝘀 𝗿𝗲𝗮𝗱 → 𝗺𝗼𝗱𝗶𝗳𝘆 → 𝘄𝗿𝗶𝘁𝗲. If two threads interleave those steps, the result changes. That was the moment I stopped thinking of programs as just logic. They are 𝗹𝗼𝗴𝗶𝗰 + 𝘁𝗶𝗺𝗲 + 𝘀𝗵𝗮𝗿𝗲𝗱 𝘀𝘁𝗮𝘁𝗲. 𝗕𝘂𝘁 𝘄𝗵𝗮𝘁 𝗶𝘀 𝗺𝘂𝗹𝘁𝗶𝘁𝗵𝗿𝗲𝗮𝗱𝗶𝗻𝗴❓ At a basic level, it means running multiple threads inside one program. Instead of doing tasks one by one, the program can be doing 𝘴𝘦𝘷𝘦𝘳𝘢𝘭 𝘵𝘢𝘴𝘬𝘴 𝘢𝘵 𝘵𝘩𝘦 𝘴𝘢𝘮𝘦 𝘵𝘪𝘮𝘦. Why do we use it? 🟢 𝗧𝗼 𝘂𝘀𝗲 𝗺𝘂𝗹𝘁𝗶𝗽𝗹𝗲 𝗖𝗣𝗨 𝗰𝗼𝗿𝗲𝘀 🟢 𝗧𝗼 𝗶𝗺𝗽𝗿𝗼𝘃𝗲 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 🟢 𝗧𝗼 𝗸𝗲𝗲𝗽 𝗮𝗽𝗽𝗹𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀 𝗿𝗲𝘀𝗽𝗼𝗻𝘀𝗶𝘃𝗲 🟢 𝗧𝗼 𝗿𝘂𝗻 𝗯𝗮𝗰𝗸𝗴𝗿𝗼𝘂𝗻𝗱 𝘁𝗮𝘀𝗸𝘀 Sounds simple but... ...once threads start sharing memory, things get complicated. You can run into: 🟡 𝗥𝗮𝗰𝗲 𝗰𝗼𝗻𝗱𝗶𝘁𝗶𝗼𝗻𝘀 🟡 𝗗𝗮𝘁𝗮 𝗶𝗻𝗰𝗼𝗻𝘀𝗶𝘀𝘁𝗲𝗻𝗰𝗶𝗲𝘀 🟡 𝗗𝗲𝗮𝗱𝗹𝗼𝗰𝗸𝘀 🟡 𝗩𝗶𝘀𝗶𝗯𝗶𝗹𝗶𝘁𝘆 𝗶𝘀𝘀𝘂𝗲𝘀 It changes how you think about correctness. Now it’s not only “𝘸𝘩𝘢𝘵 𝘩𝘢𝘱𝘱𝘦𝘯𝘴” but also “𝘸𝘩𝘦𝘯 𝘪𝘵 𝘩𝘢𝘱𝘱𝘦𝘯𝘴”. #Java #Multithreading #SoftwareEngineering #Backend #Programming

  • No alternative text description for this image

Interesting way to frame it. that moment when you realize time is part of the input really changes how you think about programs. Even in frontend we run into similar ideas with async code and event loops: the logic might be correct, but the order in which things resolve can completely change the outcome

The counter++ example is the one that tends to actually land for people who have not hit this problem yet. It looks so harmless that the idea of it being a three step operation with a race window in between feels almost insulting until you see it fail in production.

Good post. Concurrency is one of the most difficult parts of learning a programming language, especially for me

I remember getting grilled on this at university! 😐

Danila Dukhovskoi

Frontend developer 8+ years, Typescript | Javascript | React | Next | Golang | Python | Node.js | AWS | Kubernetes

1mo

Race conditions are fun because the bug disappears the moment you try to debug it. Truly quantum software behavior

I remember the same realization. Everything feels deterministic until concurrency enters the picture — then suddenly execution order becomes part of the problem

See more comments

To view or add a comment, sign in

Explore content categories