<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Level Up Your Programming with Nitin: Multithreading]]></title><description><![CDATA[Thinking in Threads — A Java Concurrency Series for the Curious Mind]]></description><link>https://nitinsingh717.substack.com/s/threads</link><image><url>https://substackcdn.com/image/fetch/$s_!OSSG!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef8448b-7d22-408c-9fb9-6a4c072fb859_1024x1024.png</url><title>Level Up Your Programming with Nitin: Multithreading</title><link>https://nitinsingh717.substack.com/s/threads</link></image><generator>Substack</generator><lastBuildDate>Tue, 26 May 2026 19:43:24 GMT</lastBuildDate><atom:link href="https://nitinsingh717.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nitin Singh]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[nitinsingh717@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[nitinsingh717@substack.com]]></itunes:email><itunes:name><![CDATA[Nitin Singh]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nitin Singh]]></itunes:author><googleplay:owner><![CDATA[nitinsingh717@substack.com]]></googleplay:owner><googleplay:email><![CDATA[nitinsingh717@substack.com]]></googleplay:email><googleplay:author><![CDATA[Nitin Singh]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Blog 5: The Lock on the Door: Synchronized, Intrinsic Locks, and Critical Sections]]></title><description><![CDATA[Locks don&#8217;t make your program safe. Correctly placed locks do]]></description><link>https://nitinsingh717.substack.com/p/blog-5-the-lock-on-the-door-synchronized</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/blog-5-the-lock-on-the-door-synchronized</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sat, 16 May 2026 05:30:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fSqd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Thinking in Threads &#8212; Part 5 | ~14 min read</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fSqd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fSqd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fSqd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:605853,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194177306?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fSqd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!fSqd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc11839c1-07f7-42dc-90a6-280cc4822ce4_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>1. The Shared Room</h3><p>Picture a records room inside a busy office.</p><p>Important documents live there. Financial reports. Employee contracts. Client data. Multiple people need access throughout the day &#8212; some to read, some to update.</p><p>Reading is fine. Ten people can read the same document simultaneously. No conflict. No corruption.</p><p>But updating is different. If two people pick up the same contract and start making changes at the same time &#8212; one person&#8217;s edits overwrite the other&#8217;s. The document ends up in an inconsistent state. Nobody&#8217;s fault. No malicious intent. Just two people, one shared resource, no coordination.</p><p>The solution is obvious. <strong>Put a lock on the door.</strong></p><p>One person enters at a time. They do their work. They leave. The next person enters.</p><p>The documents are now safe. Not because access was removed &#8212; people still need to get in. But because <strong>uncontrolled access</strong> was replaced with <strong>coordinated access.</strong></p><blockquote><p><em>&#8220;The problem was never access. It was uncontrolled access.&#8221;</em></p></blockquote><p>This is exactly what <code>synchronized</code> does in Java.</p><div><hr></div><h3>2. From the Room to Java</h3><p>The mapping is direct:</p><ul><li><p>The shared room = your shared object on the heap</p></li><li><p>The people = your threads</p></li><li><p>The lock on the door = <code>synchronized</code></p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;19f5428c-ede0-426e-84d2-6448035c03b3&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class RecordsRoom {
    private int documentVersion = 1; // shared data &#8212; the "room"

    public synchronized void updateDocument(int newVersion) {
        // only one thread enters here at a time
        documentVersion = newVersion;
    }
}
</code></pre></div><p>The moment you add <code>synchronized</code> &#8212; Java puts a lock on the door. One thread enters. The others wait outside. When the first thread finishes and leaves, the next one enters.</p><p>No two threads are ever inside simultaneously. The shared state is protected.</p><p>But before we go further &#8212; there are three terms you will hear used interchangeably for this mechanism. Let&#8217;s clear them up once and move on.</p><div><hr></div><h3>3. Three Names. One Idea.</h3><p>When developers talk about how <code>synchronized</code> works under the hood, they use three terms:</p><ul><li><p><strong>Intrinsic lock</strong> &#8212; the lock built into every Java object by default</p></li><li><p><strong>Monitor</strong> &#8212; another name for the same lock, from the formal concurrency theory</p></li><li><p><strong>Object lock</strong> &#8212; same thing, named from a practical Java perspective</p></li></ul><blockquote><p><em>&#8220;Different names. Same idea.&#8221;</em></p></blockquote><p>Every object in Java &#8212; every single one &#8212; carries an intrinsic lock. You don&#8217;t create it. You don&#8217;t declare it. It is just there, attached to the object, waiting to be used.</p><p><code>synchronized</code> is the keyword that tells Java: <em>use that built-in lock.</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;c9382d7f-cd4b-4228-a145-fd2d49b4aa83&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class RecordsRoom {
    // this object has an intrinsic lock
    // synchronized uses it automatically
    public synchronized void updateDocument(int version) {
        documentVersion = version;
    }
}
</code></pre></div><p>When Thread A calls <code>updateDocument()</code>, it <strong>acquires</strong> the intrinsic lock on the <code>RecordsRoom</code> object. </p><p>Thread B tries to call the same method &#8212; it cannot acquire the lock because Thread A holds it. </p><p>Thread B <strong>waits</strong>. Thread A finishes, <strong>releases</strong> the lock. Thread B acquires it and proceeds.</p><blockquote><p>One at a time. Coordinated. Safe.</p></blockquote><div><hr></div><h3>4. The Critical Section &#8212; The Only Part That Needs Protection</h3><p>Here is the most important concept in this entire blog.</p><p>You do not protect your entire method. You protect the <strong>critical section</strong> &#8212; the specific lines of code that read and modify shared state.</p><blockquote><p><em>&#8220;You don&#8217;t lock the house. You lock the room that has valuables.&#8221;</em></p></blockquote><p>A method can have many lines. Most of them may be pure logic &#8212; validation, computation, logging &#8212; that touches no shared state and needs no protection. Protecting those lines is waste. It forces threads to queue up for work that could safely run in parallel.</p><p>The critical section is the minimum necessary region:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;914b5774-1e8a-4491-8d79-65a15801a919&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class VisitorCounter {
    private int count = 0; // shared state

    public void recordVisit(String visitorName) {
        // not shared state &#8212; safe to run in parallel
        validateName(visitorName);
        logVisitAttempt(visitorName);

        // &#9989; critical section &#8212; this is the only part that needs protection
        synchronized (this) {
            count++; // read + modify + write on shared state
        }

        // not shared state &#8212; safe to run in parallel
        sendWelcomeNotification(visitorName);
    }
}
</code></pre></div><p><code>validateName()</code>, <code>logVisitAttempt()</code>, <code>sendWelcomeNotification()</code> &#8212; all running freely in parallel. No lock needed. No thread waiting unnecessarily.</p><p>Only <code>count++</code> &#8212; the one line that touches shared state &#8212; is inside the synchronized block.</p><p>That is surgical locking. That is the goal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jWuY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jWuY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jWuY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b397c3a-1fe3-42f9-903c-a73ee237fc03_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!jWuY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!jWuY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6ec646-395c-487d-a67e-df16bb5ce518_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>5. Synchronized Method vs Synchronized Block</h3><p>Java gives you two ways to use <code>synchronized</code>. They are not the same. Knowing the difference is the difference between a developer who uses concurrency and one who understands it.</p><div><hr></div><h4>Method-Level Synchronization &#8212; Easy, but Broad</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;d9f4073c-50db-4689-b206-ac01cbdce212&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class BankAccount {
    private int balance = 10000;
    private String ownerName = "Priya";

    // entire method is locked
    public synchronized void deposit(int amount) {
        validateAmount(amount);      // &#8592; doesn't need lock
        logTransaction(amount);      // &#8592; doesn't need lock
        balance += amount;           // &#8592; needs lock
        sendConfirmation(amount);    // &#8592; doesn't need lock
    }
}
</code></pre></div><p>When Thread A enters <code>deposit()</code>, it holds the lock for the <strong>entire method duration</strong> &#8212; including <code>validateAmount()</code>, <code>logTransaction()</code>, and <code>sendConfirmation()</code>. </p><p>Thread B waits through all of that. Even the parts that could safely run in parallel.</p><blockquote><p><em>&#8220;Method-level is easy. Block-level is precise.&#8221;</em></p></blockquote><div><hr></div><h4>Block-Level Synchronization &#8212; Precise, Performant</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;3048fb62-e1ea-4919-bdc2-21c76425107e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class BankAccount {
    private int balance = 10000;
    private final Object lock = new Object();

    public void deposit(int amount) {
        validateAmount(amount);   // runs freely in parallel &#9989;
        logTransaction(amount);   // runs freely in parallel &#9989;

        synchronized (lock) {
            balance += amount;    // only this is protected &#128274;
        }

        sendConfirmation(amount); // runs freely in parallel &#9989;
    }
}
</code></pre></div><p>Threads only queue for the one line that actually needs protection. Everything else runs in parallel. This is the correct mental model.</p><p><strong>Method-level</strong> &#8212; when the entire method touches shared state, or when simplicity matters more than performance.</p><p><strong>Block-level</strong> &#8212; when only part of the method touches shared state. Almost always the better choice.</p><div><hr></div><h3>6. Object Lock vs Class Lock &#8212; Interview Gold</h3><p>Not all <code>synchronized</code> locks are the same. This is one of the most common interview topics &#8212; and one of the most commonly misunderstood.</p><p><strong>Instance method synchronization &#8594; locks the object</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;eb0d0cd1-a6ef-40db-94cd-ab632596e4de&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // locks THIS specific Counter instance
    }
}

Counter counterA = new Counter();
Counter counterB = new Counter();

// Thread 1 locks counterA &#8594; Thread 2 can still access counterB freely
// They are different objects with different intrinsic locks
</code></pre></div><p>Two different <code>Counter</code> objects &#8212; two different locks. Threads operating on different instances never block each other.</p><p><strong>Static method synchronization &#8594; locks the Class</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;0a62854f-77da-4a3d-967d-2d19697ca15b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Counter {
    private static int totalCount = 0; // shared across ALL instances

    public static synchronized void incrementTotal() {
        totalCount++; // locks the Counter CLASS itself
    }
}

// Thread 1 and Thread 2 both call Counter.incrementTotal()
// They share ONE class-level lock &#8212; they must take turns
// regardless of which instance they came from
</code></pre></div><p>Static synchronization locks the <code>Class</code> object &#8212; one lock shared across every instance of that class, across the entire JVM.</p><blockquote><p><em>&#8220;Not all locks are the same. It depends on what you are locking.&#8221;</em></p></blockquote><ul><li><p>Instance state &#8594; instance lock. </p></li><li><p>Static/class state &#8594; class lock. </p></li></ul><p>Match the lock to the data it protects.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1TvI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1TvI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1TvI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ee53acc-53b0-4728-a2d2-7df2a04fa782_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!1TvI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!1TvI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ed5c7f3-3765-400e-a258-c1dc556c67f6_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>7. The Big Mistake &#8212; Over-Synchronization</h3><p>You now understand what <code>synchronized</code> does. Here is the most expensive mistake you can make with it.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;1a69e583-e489-450a-8dea-0ba1da498aa7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// &#10060; Over-synchronized &#8212; locking everything
public class UserService {
    private List&lt;String&gt; activeUsers = new ArrayList&lt;&gt;();

    public synchronized void addUser(String user) { ... }
    public synchronized void removeUser(String user) { ... }
    public synchronized String getUserCount() { ... }      // read-only
    public synchronized void sendWelcomeEmail(String user) { ... } // no shared state
    public synchronized void logActivity(String user) { ... }      // no shared state
}
</code></pre></div><p><code>sendWelcomeEmail()</code> touches no shared state. Neither does <code>logActivity()</code>. But because they are <code>synchronized</code>, every thread calling them must acquire the same object lock &#8212; and wait for every other synchronized method to finish first.</p><p>The result: a queue. One thread doing email sending holds the lock. A thread trying to add a user waits. A thread trying to log activity waits. Everyone waits for everyone.</p><blockquote><p><em>&#8220;You locked the entire building when only one drawer needed protection.&#8221;</em></p></blockquote><p>Fifteen chefs. One spoon. Nobody is cooking.</p><div><hr></div><h3>8. Why This Kills Performance</h3><p>The damage from over-synchronization is not hypothetical. It is measurable and severe.</p><ul><li><p>&#128308; <strong>Threads blocked</strong> &#8212; waiting to acquire a lock they don&#8217;t actually need</p></li><li><p>&#128308; <strong>CPU underutilized</strong> &#8212; cores sitting idle while threads wait in line</p></li><li><p>&#128308; <strong>Throughput collapses</strong> &#8212; under load, the queue grows faster than it drains</p></li><li><p>&#128308; <strong>Latency spikes</strong> &#8212; requests that should take milliseconds now wait seconds</p></li></ul><pre><code><code>// Scenario: 1000 threads calling UserService simultaneously

// With over-synchronization:
// &#8594; all 1000 threads queue on the same lock
// &#8594; throughput: effectively single-threaded
// &#8594; latency: 1000x worse than necessary

// With precise synchronization:
// &#8594; only the threads modifying shared state queue
// &#8594; threads doing email, logging run freely in parallel
// &#8594; throughput: genuinely concurrent
</code></code></pre><blockquote><p><em>&#8220;A poorly synchronized program is just a slow single-threaded program.&#8221;</em></p></blockquote><p>You introduced threads to gain speed. Over-synchronization takes that speed away &#8212; silently, under load, in production.</p><div><hr></div><h3>9. The Right Way to Think About Locking</h3><p>There is a simple mental checklist before you place any <code>synchronized</code>:</p><ul><li><p>&#9989; Does this code access shared state on the heap?</p></li><li><p>&#9989; Does it modify that state &#8212; not just read it?</p></li><li><p>&#9989; Can another thread be doing the same thing simultaneously?</p></li></ul><p>If yes to all three &#8212; protect it. Precisely. With a block, not the whole method if avoidable.</p><p>If no to any one &#8212; leave it alone. Let it run free. That is where your performance lives.</p><blockquote><p><em>&#8220;Thread safety is not about maximum locking. It is about minimum necessary locking.&#8221;</em></p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;275db29c-0e98-4d51-8532-dff926812c95&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// The right mental model in code
public void processOrder(Order order) {
    // pure logic &#8212; no shared state &#8212; run free
    validateOrder(order);
    calculatePricing(order);

    // shared state modification &#8212; protect precisely
    synchronized (inventoryLock) {
        inventory.deduct(order.getItems());
    }

    // no shared state &#8212; run free
    sendOrderConfirmation(order);
    logOrderProcessed(order);
}</code></pre></div><p>Small lock. Targeted lock. Everything else parallel.</p><div><hr></div><h3>10. What synchronized Actually Guarantees</h3><p>This is worth being precise about &#8212; because Blog 6 and 7 will build on it.</p><p><code>synchronized</code> gives you <strong>two guarantees</strong>, not one:</p><p><strong>Mutual exclusion</strong> &#8212; only one thread can hold the lock and execute the critical section at a time. This fixes the <strong>lost update</strong> from Blog 4.</p><p><strong>Visibility</strong> &#8212; when a thread releases a lock, all writes it made are flushed to main memory. When another thread acquires the same lock, it sees those writes. This fixes the <strong>stale read</strong> from Blog 4.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;e77e1c35-5416-4283-a902-915f6b73deee&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">synchronized (lock) {
    // entering: guaranteed to see all writes made by the
    // last thread that held this lock

    balance += amount;

    // exiting: all writes made here are guaranteed to be
    // visible to the next thread that acquires this lock
}
</code></pre></div><p>One keyword. Two guarantees. Both the atomicity failure and the visibility failure from Blog 4 &#8212; solved together.</p><p>This is why <code>synchronized</code> is the foundational tool. Everything else in the concurrency toolkit is either a refinement of it or a solution to the new problems it creates.</p><div><hr></div><h3>11. Connecting the Whole Map</h3><p>Let&#8217;s place this precisely in the journey so far:</p><ul><li><p><strong>Blog 1</strong> &#8594; shared state needs surgical protection, not blanket locking</p></li><li><p><strong>Blog 2</strong> &#8594; shared state lives on the heap, accessible to all threads</p></li><li><p><strong>Blog 3</strong> &#8594; race conditions happen when threads access shared heap state simultaneously</p></li><li><p><strong>Blog 4</strong> &#8594; race conditions produce lost updates (atomicity) and stale reads (visibility)</p></li><li><p><strong>Blog 5</strong> &#8594; <code>synchronized</code> closes the critical section, provides mutual exclusion and visibility</p></li></ul><blockquote><p><em>&#8220;Race conditions happen when critical sections are unprotected. Synchronized protects them.&#8221;</em></p></blockquote><p>The problem was always the unprotected gap. <code>synchronized</code> closes that gap. But only if placed correctly, sized precisely, and used with understanding &#8212; not fear.</p><div><hr></div><h3>12. One Line to Remember</h3><blockquote><p><em>&#8220;Locks don&#8217;t make your program safe. Correctly placed locks do.&#8221;</em></p></blockquote><p>A lock in the wrong place is not neutral. It slows your program down. It creates new coordination problems. It can even cause deadlocks &#8212; which is exactly where this series goes next.</p><div><hr></div><h3>Let&#8217;s Connect</h3><blockquote><p>If this was useful, consider sharing it with someone who&#8217;s on the same journey.</p></blockquote><div class="callout-block" data-callout="true"><p>I write every week about DSA, Java Backend Engineering, System Design, Distributed Systems, and Developer Career Growth &#8212; the stuff that actually matters for growing into a senior engineer.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Let&#8217;s keep learning together!</p><p>Have a question or a topic you&#8217;d like me to cover? Drop a comment below &#8212; I read every one.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/p/blog-5-the-lock-on-the-door-synchronized/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/p/blog-5-the-lock-on-the-door-synchronized/comments"><span>Leave a comment</span></a></p><p><em>Nitin</em><br><strong><a href="https://hashnode.com/@ns717">Hashnode</a></strong> <strong>|</strong> <strong><a href="https://nitinsingh717.substack.com/">Substack</a></strong> <strong>|</strong> <strong><a href="https://www.linkedin.com/in/nitinsingh717/">LinkedIn</a></strong> <strong>|</strong> <strong><a href="http://youtube.com/@nitinsingh717">Youtube</a></strong> <strong>|</strong> <strong><a href="https://www.instagram.com/ns717.dev/">Instagram</a></strong> <strong>|</strong> <strong><a href="https://github.com/ns717">GIT</a></strong> <strong>|</strong> <strong><a href="https://topmate.io/nitinsingh717/">Topmate</a></strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Level Up Your Programming with Nitin&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Level Up Your Programming with Nitin</span></a></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Blog 4: The Lost Update and the Stale Read: Two Bugs That Hide in Plain Sight]]></title><description><![CDATA[Some bugs scream. These two whisper &#8212; and that is what makes them lethal.]]></description><link>https://nitinsingh717.substack.com/p/blog-4-the-lost-update-and-the-stale</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/blog-4-the-lost-update-and-the-stale</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sat, 09 May 2026 05:30:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7N3I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Series: Thinking in Threads &#8212; Part 4 | ~13 min read</p></blockquote><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7N3I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7N3I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7N3I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1105024,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194177286?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7N3I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!7N3I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5ab0d11-38f1-4848-b513-06c259b157da_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>1. The Morning the Numbers Stopped Making Sense</h3><p>It is 9 AM. The support team opens a ticket.</p><p>A user transferred &#8377;5,000 to a friend last night. The money left their account. </p><ul><li><p>It never arrived. </p></li><li><p>No error was shown. </p></li><li><p>No failure was logged. </p></li><li><p>The transaction marked itself as successful.</p></li></ul><p>The money didn&#8217;t go anywhere wrong. It simply &#8212; vanished. Updated into nothing.</p><ul><li><p>You open the codebase. </p></li><li><p>The transfer logic is correct. </p></li><li><p>The database write is there. </p></li><li><p>The logs show success on both ends.</p></li></ul><p>And yet &#8212; the balance on the receiving end never changed.</p><p>This is not a logic bug. This is not a network failure. This is a <strong>lost update</strong> &#8212; one of the two bugs this blog is about. And it is sitting in perfectly readable, logically correct Java code, completely invisible until the damage is done.</p><div><hr></div><h3>2. Two Bugs. One Root. Completely Different Symptoms.</h3><p><a href="https://open.substack.com/pub/nitinsingh717/p/blog-3-race-to-disaster-understanding?r=dlqye&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true">Blog 3</a> introduced race conditions &#8212; the general category of problem that happens when threads access shared state without coordination.</p><p>Blog 4 goes one level deeper. Inside the world of race conditions, there are two specific bugs that developers encounter constantly and almost never correctly diagnose:</p><ul><li><p><strong>The Lost Update</strong> &#8212; a write that gets overwritten before anyone sees it</p></li><li><p><strong>The Stale Read</strong> &#8212; a read that sees old data, long after the truth has changed</p></li></ul><p>They feel different. They show up differently. They confuse you in different ways.</p><p>But they share one root cause &#8212; <strong>unprotected shared state on the heap.</strong></p><p>Let&#8217;s meet them one at a time.</p><div><hr></div><h3>3. The Lost Update &#8212; Your Write Never Happened</h3><h4>The Story</h4><p>Imagine a shared Google Doc. Two editors, working simultaneously.</p><ul><li><p>Editor A opens the document. It reads: <em>&#8220;Meeting at 3 PM.&#8221;</em> </p></li><li><p>Editor B opens the same document at the same moment. Also reads: <em>&#8220;Meeting at 3 PM.&#8221;</em></p></li><li><p>Editor A changes it to: <em>&#8220;Meeting at 4 PM.&#8221;</em> Saves. </p></li><li><p>Editor B changes it to: <em>&#8220;Meeting cancelled.&#8221;</em> Saves.</p></li><li><p>Editor B&#8217;s save overwrites Editor A&#8217;s change completely.</p></li><li><p>Editor A&#8217;s update &#8212; gone. Lost. As if it never happened.</p></li></ul><p>Nobody deleted it intentionally. Nobody made a mistake. Two writers, one shared document, no coordination. One update lost forever.</p><h4>In Java</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a2e0c69c-aa04-4c96-ac73-7fafca20ad14&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class SharedDocument {
    private String content = "Meeting at 3 PM"; // shared state on heap

    public void update(String newContent) {
        // step 1: read (implicit &#8212; we just overwrite)
        content = newContent; // step 2: write
    }
}
</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;3e63e894-ad52-40fe-91d3-6e162593cb56&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">SharedDocument doc = new SharedDocument();

Thread editorA = new Thread(() -&gt; doc.update("Meeting at 4 PM"));
Thread editorB = new Thread(() -&gt; doc.update("Meeting cancelled"));

editorA.start();
editorB.start();
</code></pre></div><p>Whichever thread writes last &#8212; wins. The other update is gone.</p><p>Now make it slightly more realistic &#8212; a counter instead of a string:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;a7f15968-38d9-4a03-98b6-1d1f053a90d9&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class VisitorCounter {
    private int count = 0;

    public void recordVisit() {
        int current = count;   // READ
        count = current + 1;   // WRITE
    }
}
</code></pre></div><pre><code><code>Thread A reads count = 100
Thread B reads count = 100
Thread A writes count = 101
Thread B writes count = 101  &#8592; Thread A's increment is lost
</code></code></pre><p>Two visits recorded. Counter moved by one. <strong>One update lost.</strong></p><p>No exception. No log. Just a number that is quietly, consistently wrong &#8212; and getting more wrong with every lost update.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!P1Z4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!P1Z4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!P1Z4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/359240a2-178b-491c-9cc9-f8c7806e12d5_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!P1Z4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!P1Z4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09beef68-77cf-46b9-b1c7-370c3a142cca_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h4>What Makes It a Lost Update Specifically</h4><p>The lost update is an <strong>atomicity failure.</strong></p><p>The operation &#8212; read, then write &#8212; must happen as one uninterrupted unit. When another thread steps into the gap between the read and the write, the first thread&#8217;s work is erased.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;f1565c50-41cd-47fd-b223-bfc33a34eb69&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// This is NOT atomic &#8212; it is three steps with gaps between them
count++;

// Broken down:
int temp = count;      // gap here &#8592; another thread can step in
temp = temp + 1;
count = temp;          // gap here &#8592; another thread can overwrite this
</code></pre></div><p>The fix requires making the read-modify-write sequence atomic &#8212; uninterruptible. But that is Blog 5. For now, understand the shape of the problem.</p><div><hr></div><h3>4. The Stale Read &#8212; Seeing a World That No Longer Exists</h3><h4>The Story</h4><p>You check the weather app at 7 AM. It says sunny. &#9728;&#65039; &#9728;&#65039; &#9728;&#65039; &#9728;&#65039; &#9728;&#65039;</p><p>You leave the house without an umbrella.</p><p>At noon it is raining. &#127783;&#65039; &#127783;&#65039; &#127783;&#65039; &#127783;&#65039;</p><p>The weather changed at 9 AM. Your app &#8212; due to a caching issue &#8212; never fetched the update. You made a real-world decision based on data that was accurate once but had since become a lie.</p><p>That is a stale read. You read a value. The value was true when you read it. By the time you acted on it &#8212; it was wrong.</p><h4>In Java</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;04e1115e-c5e2-48fb-9a9b-2caaa586f0b7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class FeatureFlag {
    private boolean featureEnabled = false; // shared state on heap

    public void enable() {
        featureEnabled = true; // Thread B writes this
    }

    public void processRequest() {
        if (featureEnabled) { // Thread A reads this
            runNewFeature();
        } else {
            runOldFeature(); // Thread A keeps running old feature
        }                    // even after Thread B enabled the new one
    }
}
</code></pre></div><ul><li><p>Thread B calls <code>enable()</code>. Sets <code>featureEnabled = true</code>.</p></li><li><p>Thread A calls <code>processRequest()</code>. Reads <code>featureEnabled</code>. Sees <code>false</code>.</p></li><li><p>But &#8212; Thread B already set it to <code>true</code>. How is Thread A still seeing <code>false</code>?</p></li></ul><blockquote><p>Welcome to the visibility problem.</p></blockquote><div><hr></div><h4>Why Thread A Sees Stale Data &#8212; The CPU Cache Problem</h4><p>This is where the stale read gets genuinely interesting &#8212; and where most explanations stop being honest.</p><p>Modern CPUs don&#8217;t read directly from main memory on every operation. That would be too slow. Instead, each CPU core has its own <strong>cache</strong> &#8212; a small, fast local copy of memory values it has recently used.</p><pre><code><code>Main Memory:   featureEnabled = true   &#8592; Thread B wrote this

CPU Core 1 cache:  featureEnabled = false  &#8592; Thread A reads THIS
CPU Core 2 cache:  featureEnabled = true   &#8592; Thread B wrote here first
</code></code></pre><ul><li><p>Thread B runs on Core 2. Updates <code>featureEnabled</code> to <code>true</code> in Core 2&#8217;s cache. Eventually flushes to main memory.</p></li><li><p>Thread A runs on Core 1. Has its own cached copy &#8212; still <code>false</code>. Never told to refresh it.</p></li><li><p>Thread A reads stale data. Not because of a timing gap between steps. But because <strong>the update was never made visible to it.</strong></p></li></ul><p>This is a <strong>visibility failure</strong> &#8212; a completely different category from the lost update.</p><pre><code><code>// Thread B sets this to true
private boolean featureEnabled = false;

// Thread A may never see the update
// because the JVM and CPU are not required
// to make writes visible across threads
// without explicit coordination
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NeRY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NeRY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 424w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 848w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 1272w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NeRY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png" width="1077" height="264" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d936342-d74b-4015-801e-1c63087f321a_1077x264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:264,&quot;width&quot;:1077,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:186509,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194177286?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NeRY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 424w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 848w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 1272w, https://substackcdn.com/image/fetch/$s_!NeRY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d936342-d74b-4015-801e-1c63087f321a_1077x264.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>5. Atomicity Failure vs Visibility Failure &#8212; The Distinction That Matters</h3><p>Most developers lump these together. They are not the same problem. They do not have the same solution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3kDC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3kDC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 424w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 848w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 1272w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3kDC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png" width="731" height="320" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6b27d95-468b-40f1-bf0f-407a5ea7a474_731x320.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:320,&quot;width&quot;:731,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50531,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194177286?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6b27d95-468b-40f1-bf0f-407a5ea7a474_731x320.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3kDC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 424w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 848w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 1272w, https://substackcdn.com/image/fetch/$s_!3kDC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9bc07f7-2e6e-4b7f-8d1e-705a3536c062_731x320.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;e31bd26d-849a-414b-b904-5f4c889407bb&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Atomicity failure &#8212; two threads, one shared counter
public void increment() {
    count++; // read-modify-write &#8212; not atomic &#8212; lost updates possible
}

// Visibility failure &#8212; one thread writes, another never sees it
private boolean running = true;

// Thread A:
while (running) { doWork(); } // may loop forever &#8212; never sees Thread B's write

// Thread B:
running = false; // written to cache, may never reach Thread A's view
</code></pre></div><p>Two different bugs. Both silent. Both produce wrong results. Both hide in plain sight.</p><div><hr></div><h3>6. Why They Feel Like Ghost Bugs &#128123;</h3><p>Lost updates and stale reads share one brutal characteristic &#8212; they leave no evidence.</p><p><strong>The lost update:</strong></p><ul><li><p>No exception thrown</p></li><li><p>No write failed &#8212; it succeeded, it just got overwritten</p></li><li><p>Logs show the operation completed</p></li><li><p>The data is just quietly wrong</p></li></ul><p><strong>The stale read:</strong></p><ul><li><p>No exception thrown</p></li><li><p>The read succeeded &#8212; it returned a value</p></li><li><p>The value was accurate at some point in time</p></li><li><p>The thread just never got the memo that reality changed</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;f6554eab-30d4-4357-bbc3-dc2ff17c095b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// This loop may run forever in production
// Works fine in single-threaded tests
// Works fine with certain JVM flags
// Breaks silently under specific CPU + JVM combinations

private boolean shutdown = false;

public void run() {
    while (!shutdown) { // reads stale 'false' forever
        processNextTask();
    }
}

public void stop() {
    shutdown = true; // written &#8212; but Thread A may never see it
}
</code></pre></div><p>You test this. It works. You ship it. A month later, under specific load on specific hardware, a thread refuses to stop. Support escalates. You add logs. The thread stops &#8212; because the log statement changed the timing. You conclude it was a fluke.</p><p>It was not a fluke.</p><blockquote><p><em>&#8220;Ghost bugs are not random. They are deterministic bugs with non-deterministic triggers.&#8221;</em></p></blockquote><div><hr></div><h3>7. Why These Bugs Survive Code Review</h3><p>Here is the uncomfortable truth &#8212; these bugs are invisible to code review.</p><p>A reviewer reads this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;6bc10b8f-df92-4781-b89e-e3351eee6344&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void recordVisit() {
    count = count + 1;
}
</code></pre></div><p>The logic is correct. Addition is correct. The reviewer approves.</p><p>What the reviewer cannot see by reading:</p><ul><li><p>That <code>count</code> is on the heap</p></li><li><p>That another thread is calling this simultaneously</p></li><li><p>That the read and write are not atomic</p></li><li><p>That one update will be lost under load</p></li></ul><p>And this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;05ccdaba-1366-4c48-9522-eb46ae185444&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">while (!shutdown) {
    processNextTask();
}
</code></pre></div><p>The logic is correct. The loop condition makes sense. The reviewer approves.</p><p>What the reviewer cannot see:</p><ul><li><p>That <code>shutdown</code> may be cached on a different CPU core</p></li><li><p>That the write from another thread may never reach this thread&#8217;s view</p></li><li><p>That this loop may never terminate</p></li></ul><p>Code review catches logic bugs. It cannot catch timing bugs. It cannot catch visibility bugs. That is why these two live in production for months.</p><div><hr></div><h3>8. Connecting the Dots &#8212; Blog 1, 2, 3, 4</h3><p>Let&#8217;s place this precisely in the map we have been building:</p><ul><li><p><strong>Blog 1</strong> &#8212; Thread safety is about protecting shared state at the moment of modification</p></li><li><p><strong>Blog 2</strong> &#8212; Shared state lives on the heap. The stack is private and safe.</p></li><li><p><strong>Blog 3</strong> &#8212; Race conditions happen when threads access shared heap state without coordination</p></li><li><p><strong>Blog 4</strong> &#8212; Race conditions produce two specific bugs: lost updates (atomicity failure) and stale reads (visibility failure)</p></li></ul><pre><code><code>Shared heap state
       &#9474;
       &#9500;&#9472;&#9472; Multiple threads access without coordination
       &#9474;              &#9474;
       &#9474;    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474;    &#9474;                    &#9474;
       &#9474;  Gap between          Write not
       &#9474;  read &amp; write         made visible
       &#9474;    &#9474;                    &#9474;
       &#9474;  Lost Update          Stale Read
       &#9474;  (Atomicity)          (Visibility)
</code></code></pre><p>Every concurrency tool you will learn from Blog 5 onwards &#8212; <code>synchronized</code>, <code>volatile</code>, <code>AtomicInteger</code>, <code>locks</code> &#8212; is ultimately solving one or both of these two problems.</p><p>Understanding what you are solving before you reach for the tool is what separates a developer who uses concurrency from one who understands it.</p><div><hr></div><h3>9. No Fix Yet &#8212; Still Intentional</h3><p>Three blogs in a row now. No solution introduced.</p><p>That is by design.</p><ul><li><p>The lost update needs <strong>atomicity </strong>&#8212; the guarantee that a compound operation completes without interruption.</p></li><li><p>The stale read needs <strong>visibility </strong>&#8212; the guarantee that a write made by one thread becomes visible to other threads.</p></li><li><p>These are two distinct guarantees. They require different tools. </p></li><li><p>Using the wrong tool for the wrong problem is how developers create new bugs while trying to fix old ones.</p></li></ul><p>Blog 5 introduces <code>synchronized</code> &#8212; what it actually guarantees, what it does not, and precisely which of these two problems it solves and how.</p><blockquote><p><em>&#8220;Name the problem before you name the solution. Always.&#8221;</em></p></blockquote><div><hr></div><h3>Let&#8217;s Connect</h3><blockquote><p>If this was useful, consider sharing it with someone who&#8217;s on the same journey.</p></blockquote><div class="callout-block" data-callout="true"><p>I write every week about DSA, Java Backend Engineering, System Design, Distributed Systems, and Developer Career Growth &#8212; the stuff that actually matters for growing into a senior engineer.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Let&#8217;s keep learning together!</p><p>Have a question or a topic you&#8217;d like me to cover? Drop a comment below &#8212; I read every one.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/p/blog-4-the-lost-update-and-the-stale/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/p/blog-4-the-lost-update-and-the-stale/comments"><span>Leave a comment</span></a></p><p><em>Nitin</em><br><strong><a href="https://hashnode.com/@ns717">Hashnode</a></strong> <strong>|</strong> <strong><a href="https://nitinsingh717.substack.com/">Substack</a></strong> <strong>|</strong> <strong><a href="https://www.linkedin.com/in/nitinsingh717/">LinkedIn</a></strong> <strong>|</strong> <strong><a href="http://youtube.com/@nitinsingh717">Youtube</a></strong> <strong>|</strong> <strong><a href="https://www.instagram.com/ns717.dev/">Instagram</a></strong> <strong>|</strong> <strong><a href="https://github.com/ns717">GIT</a></strong> <strong>|</strong> <strong><a href="https://topmate.io/nitinsingh717/">Topmate</a></strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Level Up Your Programming with Nitin&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Level Up Your Programming with Nitin</span></a></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Blog 3: Race to Disaster: Understanding Race Conditions]]></title><description><![CDATA[Race conditions are not bugs in your logic &#8212; they are bugs in your timing]]></description><link>https://nitinsingh717.substack.com/p/blog-3-race-to-disaster-understanding</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/blog-3-race-to-disaster-understanding</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sat, 02 May 2026 05:30:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HD55!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Series: Thinking in Threads &#8212; Part 3 | ~13 min read</p></blockquote><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HD55!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HD55!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!HD55!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!HD55!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!HD55!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HD55!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1142190,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194176625?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HD55!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!HD55!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!HD55!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!HD55!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd685403-7f6b-43e5-a0b4-1a3ddbecdcf2_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>1. The Illusion of Correctness</h3><p>The code works.</p><ul><li><p>Tests pass. </p></li><li><p>Green across the board. </p></li><li><p>Logs look clean. </p></li><li><p>No exceptions. </p></li><li><p>No warnings. </p></li><li><p>You deploy. </p></li><li><p>You move on.</p></li></ul><p>And then &#8212; three days later &#8212; a number is wrong somewhere. </p><ul><li><p>A record is missing. </p></li><li><p>A balance doesn&#8217;t add up. </p></li><li><p>Someone files a ticket. </p></li><li><p>You open the code. </p></li><li><p>You read it line by line. </p></li><li><p>The logic is correct. </p></li><li><p>You run it locally. </p></li><li><p>It works perfectly.</p></li><li><p>You close the ticket. </p></li><li><p>Mark it as <em>&#8220;cannot reproduce.&#8221;</em></p></li></ul><p>It happens again.</p><blockquote><p><em>The most dangerous bugs are not the ones that fail every time &#8212; but the ones that fail only sometimes.</em></p></blockquote><p>This is what a race condition feels like from the outside. Not a crash. Not an error. Just a quiet, occasional wrongness that makes you question your own code &#8212; and sometimes your own sanity.</p><div><hr></div><h3>2. Let&#8217;s Count to Ten &#8212; Together</h3><p>No Java yet. Just two people and a whiteboard.</p><p>A number is written on the whiteboard: <strong>0</strong></p><p>Nitin and Shikha are both tasked with incrementing that number &#8212; each of them ten times. Simple job. Expected result: <strong>20</strong>.</p><p>Here is what each increment actually involves:</p><ul><li><p><strong>Read</strong> the current value from the whiteboard</p></li><li><p><strong>Add 1</strong> to it in your head</p></li><li><p><strong>Write</strong> the new value back to the whiteboard</p></li></ul><p>Nitin walks up. Reads <strong>0</strong>. Computes <strong>1</strong>. Writes <strong>1</strong>. &#9989;</p><p>Shikha walks up. Reads <strong>1</strong>. Computes <strong>2</strong>. Writes <strong>2</strong>. &#9989;</p><p>So far so good. But now &#8212; they both walk up at the same time.</p><ul><li><p>Nitin reads <strong>14</strong>. Shikha reads <strong>14</strong>.</p></li><li><p>Nitin computes <strong>15</strong>. Shikha computes <strong>15</strong>.</p></li><li><p>Nitin writes <strong>15</strong>. Shikha writes <strong>15</strong>.</p></li></ul><p>Two increments happened. The whiteboard moved by <strong>one</strong>.</p><p>They finish all twenty increments. The whiteboard shows <strong>17</strong>. Sometimes <strong>16</strong>. Sometimes <strong>18</strong>. Never reliably <strong>20</strong>.</p><ul><li><p>Nobody made an arithmetic mistake. </p></li><li><p>The logic was correct. </p></li><li><p>The result is wrong.</p></li></ul><blockquote><p><strong>This is a race condition.</strong></p></blockquote><div><hr></div><h3>3. What Just Happened?</h3><blockquote><p><em>&#8220;No one made a mistake. And yet the result is wrong.&#8221;</em></p></blockquote><p>This is the part that makes race conditions so disorienting.</p><ul><li><p>You look at the code &#8212; the logic is sound. </p></li><li><p>You look at the result &#8212; it is broken. </p></li></ul><blockquote><p>The gap between those two realities is where the race condition lives.</p></blockquote><p>Here is the same story in Java:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;992882d4-facd-41fc-9c25-fa05141ef918&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Counter {
    private int count = 0; // shared state &#8212; lives on the heap

    public void increment() {
        count++; // looks like one operation. it is not.
    }

    public int getCount() {
        return count;
    }
}
</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;be0b8b3e-1508-4d57-8c67-7de5b8eccd3d&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Thread nitin  = new Thread(() -&gt;  {
            for (int i = 0; i &lt; 10; i++) 
                 counter.increment();
        });
        Thread shikha = new Thread(() -&gt; {
            for (int i = 0; i &lt; 10; i++) 
                 counter.increment();
        });

        nitin.start();
        shikha.start();
        nitin.join();
        shikha.join();

        System.out.println("Final count: " + counter.getCount());
        // Expected: 20
        // Actual:   17? 18? 19? Depends on the day.
    }
}
</code></pre></div><p>Run this. Run it again. Run it ten times. You will get different answers. Same code. Same input. Different results.</p><p>That is a race condition. And that single line &#8212; <code>count++</code> &#8212; is where it lives.</p><blockquote><p>If you run this locally and always get 20 &#8212; increase the loop count to 100,000. With only 10 iterations, threads finish too fast to collide. The race condition exists, it just needs more pressure to show itself. That is exactly what makes it dangerous in production.</p></blockquote><div><hr></div><h3>4. The Core Problem &#8212; The Gap Between Steps</h3><p><code>count++</code> looks like one operation. In your source code, it is one line.</p><p>At the bytecode level, it is <strong>three separate steps:</strong></p><pre><code><code>1. READ  &#8212; load current value of count from heap into thread's working memory
2. MODIFY &#8212; add 1 to the loaded value
3. WRITE  &#8212; store the updated value back to heap
</code></code></pre><pre><code><code>// What you write:
count++;

// What actually happens: under the hood
int temp = count;      // step 1: READ
temp = temp + 1;       // step 2: MODIFY
count = temp;          // step 3: WRITE
</code></code></pre><blockquote><p><em>&#8220;The problem is not in the steps &#8212; but in the gap between them.&#8221;</em></p></blockquote><p>Another thread can step in between any of these three steps. It can read the old value before the write happens. It can overwrite a result that another thread just computed. The window is tiny &#8212; microseconds &#8212; but at scale, with thousands of operations per second, it gets hit constantly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QNgN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QNgN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QNgN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png" width="728" height="485.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10d61d2a-3468-433b-99e3-b424f17d2d0d_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!QNgN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!QNgN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8d3195d-9f4d-4079-9ee2-734c13421aba_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>5. Two Classic Patterns &#8212; Interview Gold</h3><p>Race conditions always fall into one of two patterns. </p><p><em>Learn these. You will see them everywhere.</em></p><div><hr></div><h4>&#128313; Read-Modify-Write</h4><blockquote><p><em>Read a value. Change it. Write it back.</em></p></blockquote><pre><code><code>// counter++ is the textbook example
count++;

// So is this:
balance = balance + deposit;

// And this:
retryCount = retryCount + 1;
</code></code></pre><p>Any operation that reads shared state, computes something, and writes back &#8212; is a read-modify-write. If two threads do this simultaneously without coordination, one update gets lost.</p><blockquote><p><em>&#8220;These operations look atomic but They are not.&#8221;</em></p></blockquote><div><hr></div><h4>&#128313; Check-Then-Act</h4><p>Check a condition. Assume it is still true. Act on it.</p><pre><code><code>// Looks safe. Is not.
if (balance &gt; 0) {
    withdraw(amount); // another thread may have withdrawn between the check and this line
}
</code></code></pre><pre><code><code>// Another classic:
if (!map.containsKey(key)) {
    map.put(key, value); // another thread may have inserted the same key already
}
</code></code></pre><p>The check and the act are two separate steps. Another thread can change the world between them. By the time you act, the condition you checked is no longer true.</p><blockquote><p><em>&#8220;The gap between checking and acting is where the race lives.&#8221;</em></p></blockquote><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dgU1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dgU1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 424w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 848w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 1272w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dgU1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png" width="975" height="303" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89997ce3-6ef8-4803-922b-0c4395566010_975x303.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:303,&quot;width&quot;:975,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:70280,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194176625?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89997ce3-6ef8-4803-922b-0c4395566010_975x303.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dgU1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 424w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 848w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 1272w, https://substackcdn.com/image/fetch/$s_!dgU1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57dcd92f-3a27-4bfa-ad6e-310eadd540d5_975x303.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>6. Why It Is <a href="https://en.wikipedia.org/wiki/Nondeterministic_algorithm">Non-Deterministic</a></h3><p>Here is what makes race conditions genuinely hard to reason about:</p><ul><li><p>Threads run independently</p></li><li><p>The CPU scheduler decides which thread runs when</p></li><li><p>That decision changes based on system load, available cores, OS state</p></li><li><p>You have zero control over it</p></li></ul><p>The same code, on the same machine, with the same input &#8212; can produce <strong>different results on different runs.</strong></p><pre><code><code>// Monday morning, low load:
Final count: 19  &#9989; (close enough, you don't notice)

// Friday afternoon, heavy load:
Final count: 14  &#10060; (someone notices)

// During a demo:
Final count: 20  &#9989; (of course it works now)
</code></code></pre><p>The race condition was always there. The timing just didn&#8217;t expose it until it did.</p><p>This is why race conditions survive code review. The reviewer reads the logic &#8212; the logic is correct. Nobody is reading for timing gaps. Nobody is imagining two threads stepping on each other between lines.</p><div><hr></div><h3>7. Why You Cannot Reproduce It Easily</h3><p>This is the section every senior developer will nod at.</p><blockquote><p><em>&#8220;It works on my machine.&#8221;</em></p></blockquote><p>Of course it does. Locally, you have one or two threads. The load is low. The operations complete so fast the window for collision almost never opens. The race condition exists &#8212; it just rarely gets triggered.</p><p>In production:</p><ul><li><p>Hundreds of threads, running simultaneously</p></li><li><p>High load, slower operations, longer gaps between steps</p></li><li><p>The collision window opens constantly</p></li></ul><p>And then &#8212; you try to debug it.</p><p>You add a log statement:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;b0e03d6b-a55f-4462-a8f6-f7920237119f&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public void increment() {
    System.out.println("before: " + count); // added for debugging
    count++;
    System.out.println("after: " + count);
}
</code></pre></div><p>The bug disappears. &#10024;</p><p>Not because the log fixed anything. Because <strong>logging slows the thread down.</strong> The extra time spent writing to the log changes the timing. The collision window closes. The threads stop stepping on each other.</p><p>You remove the log. Bug comes back.</p><blockquote><p><em>&#8220;The act of observing the bug changes its behavior.&#8221;</em></p></blockquote><p>This is not mysticism. It is physics. Every tool you use to observe the system &#8212; logging, breakpoints, profilers &#8212; changes the thread scheduling. The bug hides. The moment you stop looking, it returns.</p><div><hr></div><h3>8. Why This Is Dangerous &#9760;&#65039;</h3><p>Let&#8217;s be precise about what makes this category of bug genuinely serious:</p><ul><li><p>&#10060; No exception is thrown</p></li><li><p>&#10060; No crash occurs</p></li><li><p>&#10060; Nothing appears in your logs</p></li><li><p>&#10060; Your monitoring shows green</p></li><li><p>&#9989; The data is silently, consistently wrong</p></li></ul><p>A <em>NullPointerException</em> is a good bug. It tells you where it happened, when it happened, and what caused it. You fix it in an hour.</p><p>A race condition is a ghost. It corrupts data quietly. It leaves no evidence. The damage accumulates &#8212; wrong balances, duplicate records, missed updates &#8212; until someone manually checks the numbers and realizes something is deeply wrong.</p><p>By then, the cause is buried under millions of subsequent operations.</p><p>This is what Blog 1 meant by:</p><blockquote><p><em>&#8220;Your program is lying to you &#8212; and you don&#8217;t even know it.&#8221;</em></p></blockquote><div><hr></div><h3>9. What Developers Do Wrong</h3><p>When a race condition is suspected, the instinct is almost always wrong:</p><ul><li><p><strong>Add more logs</strong> &#8212; changes the timing, bug hides, you conclude its fixed</p></li><li><p><strong>Add retry logic</strong> &#8212; retrying a corrupt operation just corrupts it more reliably</p></li><li><p><strong>Blame the environment</strong> &#8212; <em>&#8220;must be a network issue,&#8221; &#8220;staging behaves differently&#8221;</em></p></li><li><p><strong>Add a sleep()</strong> &#8212; this one is special. It sometimes works. Which makes it worse &#8212; you&#8217;ve hidden the bug under a timing band-aid that will fail under different load.</p></li></ul><pre><code><code>// Please never do this
public void increment() {
    Thread.sleep(10); // "fixed" the race condition by hoping threads don't overlap
    count++;
}
</code></code></pre><blockquote><p><em>&#8220;You cannot fix a race condition by observing it. You fix it by understanding it.&#8221;</em></p></blockquote><p>The only real path forward is understanding exactly what is racing, where the gap is, and what coordination mechanism closes it.</p><p>That coordination &#8212; the fix &#8212; is not this blog. </p><p>This blog&#8217;s job is to make the problem undeniable.</p><div><hr></div><h3>10. No Fix Yet &#8212; And That Is Intentional</h3><p>This blog deliberately ends without a solution.</p><p><em>No synchronized</em>. No <em>locks</em>. No <em>AtomicInteger</em>. Nothing.</p><p>Because before you reach for a tool, you need to see the problem with absolute clarity. Developers who jump to <em>synchronized </em>without understanding race conditions add it in the wrong places, miss the actual critical section, and create new problems &#8212; deadlocks, performance collapse, false safety.</p><blockquote><p><em>&#8220;Before you control the system, you must first see the problem clearly.&#8221;</em></p></blockquote><p>The fix comes in Blog 5. Between now and then &#8212; sit with the discomfort. That discomfort is the beginning of real understanding.</p><div><hr></div><h3>11. Connecting Back &#8212; Stack, Heap, Race</h3><p>From Blog 2 &#8212; the heap is shared territory. The stack is private.</p><p>Race conditions only happen on the heap:</p><pre><code><code>public void increment() {
    int temp = count;  // 'temp' &#8594; stack &#8594; private &#8594; safe
    temp = temp + 1;   // computation &#8594; stack &#8594; safe
    count = temp;      // 'count' &#8594; heap &#8594; shared &#8594; THIS is where the race happens
}
</code></code></pre><p>The stack operations are completely safe. Each thread has its own <code>temp</code>. No conflict possible there.</p><p>The single write back to <code>count</code> on the heap &#8212; that is the entire problem.</p><blockquote><p><em>&#8220;Threads don&#8217;t race over logic. They race over shared data.&#8221;</em></p></blockquote><p>Every race condition you will ever encounter traces back to this: shared mutable state on the heap, accessed by multiple threads, with a gap between the read and the write.</p><div><hr></div><h3>12. One Line to Remember</h3><blockquote><p><em>&#8220;Race conditions are not bugs in your logic &#8212; they are bugs in your timing.&#8221;</em></p></blockquote><p>Your logic can be perfectly correct. Your algorithm can be sound. And your program can still produce wrong results &#8212; because the order in which threads execute those correct steps is unpredictable.</p><p>That is the nature of the race. And that is why it deserves its own blog before any solution is introduced.</p><div><hr></div><h3>&#128188; Crack the Interview &#127919;</h3><p>Q: What is a race condition?</p><p>A race condition occurs when the correctness of a program depends on the relative timing or interleaving of multiple threads. When two or more threads access shared state simultaneously &#8212; and at least one of them modifies it &#8212; the outcome varies depending on which thread executes first. The result is non-deterministic and often incorrect.</p><div><hr></div><p><strong>Q: Why is a race condition non-deterministic?</strong></p><p>Because thread scheduling is controlled by the operating system and the JVM, not by your code. The order in which threads execute their operations changes based on system load, available CPU cores, and OS scheduling decisions. The same code, with the same input, can produce different results on different runs &#8212; or even on the same run at different times.</p><div><hr></div><p><strong>Q: What is the difference between check-then-act and read-modify-write?</strong></p><p>Both are compound operations that appear atomic but are not:</p><ul><li><p><strong>Read-modify-write</strong> &#8212; read a value, change it, write it back. Example: <code>count++</code>. The danger is that another thread can read the old value between the read and the write.</p></li><li><p><strong>Check-then-act</strong> &#8212; check a condition, then act based on it. Example: <code>if (balance &gt; 0) withdraw()</code>. The danger is that another thread can change the state between the check and the action.</p></li></ul><p>Both patterns create a gap &#8212; a window in time &#8212; where another thread can step in and corrupt the result.</p><div><hr></div><p><strong>Q: Why are race conditions hard to debug?</strong></p><p>Three reasons:</p><ul><li><p>They are <strong>non-deterministic</strong> &#8212; they don&#8217;t fail consistently, so they&#8217;re hard to trigger on demand</p></li><li><p>They are <strong>observer-sensitive</strong> &#8212; adding logs, breakpoints, or profilers changes thread timing and hides the bug</p></li><li><p>They leave <strong>no evidence</strong> &#8212; no exception, no crash, just silently wrong data</p></li></ul><p>The very act of trying to observe the bug changes its behavior, making traditional debugging techniques ineffective.</p><div><hr></div><h3>Let&#8217;s Connect</h3><blockquote><p>If this was useful, consider sharing it with someone who&#8217;s on the same journey.</p></blockquote><div class="callout-block" data-callout="true"><p>I write every week about DSA, Java Backend Engineering, System Design, Distributed Systems, and Developer Career Growth &#8212; the stuff that actually matters for growing into a senior engineer.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Let&#8217;s keep learning together!</p><p>Have a question or a topic you&#8217;d like me to cover? Drop a comment below &#8212; I read every one.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/p/blog-3-race-to-disaster-understanding/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://nitinsingh717.substack.com/p/blog-3-race-to-disaster-understanding/comments"><span>Leave a comment</span></a></p><p><em>Nitin</em><br><strong><a href="https://hashnode.com/@ns717">Hashnode</a></strong> <strong>|</strong> <strong><a href="https://nitinsingh717.substack.com/">Substack</a></strong> <strong>|</strong> <strong><a href="https://www.linkedin.com/in/nitinsingh717/">LinkedIn</a></strong> <strong>|</strong> <strong><a href="http://youtube.com/@nitinsingh717">Youtube</a></strong> <strong>|</strong> <strong><a href="https://www.instagram.com/ns717.dev/">Instagram</a></strong> <strong>|</strong> <strong><a href="https://github.com/ns717">GIT</a></strong> <strong>|</strong> <strong><a href="https://topmate.io/nitinsingh717/">Topmate</a></strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Level Up Your Programming with Nitin&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Level Up Your Programming with Nitin</span></a></p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Blog 0: Before We Begin: Why This Series Exists]]></title><description><![CDATA[Threading is not about synchronization. It never was.]]></description><link>https://nitinsingh717.substack.com/p/blog-0-before-we-begin-why-this-series</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/blog-0-before-we-begin-why-this-series</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sun, 19 Apr 2026 06:35:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RQM8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Thinking in Threads &#8212; Part 0 | ~12 min read</em></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RQM8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RQM8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RQM8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1520137,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/194174249?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RQM8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!RQM8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88327c1c-6b52-4552-a97d-4d63e25cdfc1_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Moment I Realised I Had Been Thinking About It Wrong</h3><p>Twelve years into software engineering, I thought I understood threading.</p><p>I had used <code>synchronized</code>. I had written thread pools. I had debugged race conditions at 2 AM in production. I had read articles, watched talks, followed tutorials. I could answer the standard interview questions without hesitation.</p><p>And yet &#8212; something always felt incomplete.</p><p>Every resource I found said the same things. Use <code>synchronized</code>. Use <code>volatile</code>. Use <code>ReentrantLock</code>. Here is the syntax. Here is an example. Here is a quiz.</p><p>Nobody was explaining <em>why</em>.</p><p>Why does a race condition happen in the first place? Not the definition &#8212; the actual mechanical reason. </p><p>What is physically happening inside the JVM when two threads corrupt shared data? Why does <code>volatile</code> not give you thread safety even though it sounds like it should? </p><p>Why does synchronizing everything make things worse instead of better?</p><p>I kept finding answers to <em>what</em>. Nobody was giving me answers to <em>why</em>.</p><p>So I went deeper. I read the papers. I read the specs. I read the book that the entire Java concurrency ecosystem quietly considers its bible &#8212; <em>Java Concurrency in Practice</em> by Brian Goetz. Dense, precise, uncompromising. The kind of book that rewards patience with permanent clarity.</p><p>And something clicked.</p><p>Threading is not about locks. Threading is not about <code>synchronized</code>. Threading is not about any keyword or API.</p><p><strong>Threading is about state. And who can touch it. And when.</strong></p><p>Everything else &#8212; every keyword, every tool, every pattern &#8212; is just a consequence of that one idea. Once that idea is clear, the entire landscape of Java concurrency stops being a collection of rules to memorise and becomes a single coherent system to understand.</p><p>That realisation took me years to reach.</p><p>This series is my attempt to give it to you in fifteen blogs.</p><div><hr></div><h3>Why Most Concurrency Content Fails You</h3><p>Search for Java threading content. You will find the same ten topics, explained the same way, on every platform.</p><ul><li><p><em>&#8220;Here is how synchronized works.&#8221;</em></p></li><li><p><em>&#8220;Here is the difference between wait() and notify().&#8221;</em></p></li><li><p><em>&#8220;Here is how to use a thread pool.&#8221;</em></p></li></ul><p>Useful. Accurate. And completely insufficient.</p><p>Because they all start in the middle of the story.</p><p>They teach you the tools before you understand the problem. They show you <code>synchronized</code> before you truly feel why unprotected shared state is dangerous. They explain <code>volatile</code> before you understand CPU caches and why a write on one core might never reach another. They introduce locks before you have felt the weight of what happens when coordination goes wrong.</p><p>The result is developers who can use the tools but cannot reason about them. Developers who add <code>synchronized</code> to a method and feel safe &#8212; without knowing whether they protected the right thing. Developers who reach for <code>volatile</code> because it sounds like it should help &#8212; without understanding that it solves a visibility problem but does nothing for atomicity. Developers who over-synchronize everything and then wonder why their concurrent program is slower than the sequential one it replaced.</p><p>I was that developer for longer than I would like to admit.</p><p>The problem is not intelligence. The problem is sequence. Concurrency concepts taught out of order produce confusion that looks like understanding.</p><blockquote><p><em>&#8220;You cannot use a tool correctly if you do not understand what problem it was designed to solve.&#8221;</em></p></blockquote><div><hr></div><h3>What This Series Does Differently</h3><p>This series starts at the beginning. The actual beginning.</p><p>Not with <code>synchronized</code>. Not with thread pools. Not with any API at all.</p><p>It starts with a question: <strong>why does sequential thinking break the modern world?</strong> And it builds from there &#8212; one concept at a time, each one earning its place by solving a problem the previous blog created.</p><p>By the time you reach the tools, you will understand what they are solving. By the time you see <code>synchronized</code>, you will have felt the race condition it prevents. By the time you see <code>volatile</code>, you will have understood CPU caches and why visibility is a separate problem from atomicity. By the time you reach <code>CompletableFuture</code>, you will understand the entire chain of limitations that made it necessary.</p><p><strong>This is the series I wish had existed when I started.</strong></p><div><hr></div><h3>The Philosophy Behind Every Blog</h3><p>Three principles guide every word written here.</p><div><hr></div><p><strong>Feeling before fixing.</strong></p><p>Every problem in this series is introduced before its solution. You will spend three blogs understanding race conditions, lost updates, and stale reads &#8212; before a single fix is shown. This is intentional. A solution without a felt problem is just syntax. A solution that follows genuine understanding becomes intuition.</p><div><hr></div><p><strong>Analogy before abstraction.</strong></p><p>Every technical concept in this series is grounded in a real-world story first. Not because the technical details don&#8217;t matter &#8212; they do, deeply &#8212; but because the human brain understands new ideas by mapping them to things it already knows. The analogy is not a simplification. It is the fastest path to the abstraction.</p><div><hr></div><p><strong>Precision over completeness.</strong></p><p>This series does not cover everything. It covers what matters &#8212; in the right order, with the right depth, without the noise. Twelve years of software engineering has taught me that clarity is harder than comprehensiveness. Anyone can write an exhaustive reference. The harder thing is knowing what to leave out.</p><div><hr></div><h3>A Word About the Book That Influenced This Series</h3><p>There is one book in the Java ecosystem that stands apart from everything else written about concurrency.</p><p><em>Java Concurrency in Practice</em> &#8212; written by Brian Goetz and a team of engineers who actually built parts of the Java concurrency library &#8212; is the most precise, honest, and complete treatment of this subject that exists. It does not simplify. It does not hand-hold. It treats the reader as an engineer capable of handling the full truth.</p><p>I have learned more about threading from that book than from any other single source in my career.</p><p>This series is not that book. It does not try to be. <em>JCIP</em> is the definitive reference &#8212; thorough, dense, and written for engineers who are ready for that level of rigor.</p><p>This series is the bridge that makes you ready for it.</p><p>If <em>JCIP</em> is the mountain &#8212; this series is the trail that gets you to base camp. From there, the summit is yours to climb.</p><p>I owe that book a debt this series can only partially repay.</p><div><hr></div><h3>Who This Is For</h3><p>This series is for the Java developer who:</p><ul><li><p>Has used threading but never fully understood it</p></li><li><p>Can write <code>synchronized</code> but is not sure if they are putting it in the right place</p></li><li><p>Has debugged a race condition by adding a log statement &#8212; and watched the bug disappear</p></li><li><p>Has read about <code>volatile</code> three times and still is not confident about when to use it</p></li><li><p>Is preparing for a senior engineering interview and wants to actually understand concurrency, not just memorise answers</p></li><li><p>Has been in software for years and suspects there is a cleaner mental model underneath all the rules &#8212; and wants to find it</p></li></ul><p>If any of that resonates &#8212; this series was written for you.</p><div><hr></div><h3>What Twelve Years Taught Me About Threading</h3><p>I have worked across systems of very different scales. Small services. High-throughput pipelines. Real-time systems where a missed update costs money. Systems where a stale read caused a wrong decision that took days to trace back to its source.</p><p>Threading problems do not care how senior you are. They do not care how carefully you wrote the code. They care about one thing: <strong>did you understand what you were protecting, and did you protect it correctly?</strong></p><p>Most threading bugs are not caused by ignorance of the tools. They are caused by a misunderstanding of the problem. A developer who does not know about <code>synchronized</code> will not use it &#8212; and the bug is obvious. A developer who knows about <code>synchronized</code> but does not understand <em>what to protect</em> will use it in the wrong place &#8212; and the bug is invisible.</p><p>The invisible bugs are the dangerous ones.</p><blockquote><p><em>&#8220;The most expensive bugs in concurrent programming are the ones written by developers who thought they understood threading.&#8221;</em></p></blockquote><p>This series is about closing the gap between thinking you understand threading and actually understanding it. Not through intimidation. Not through exhaustive coverage of every edge case. But through a careful, patient build &#8212; from the first question to the complete mental model.</p><p>Twelve years of experience distilled into fifteen blogs.</p><p>No filler. No hand-waving. No false confidence.</p><p>Just the concepts, in the right order, explained the right way.</p><div><hr></div><h3>The Map &#8212; What We Will Cover</h3><p>Here is the journey, in order:</p><ul><li><p><strong>Blog 1 &#8212; The Need: Why Sequential Thinking Breaks the Modern World</strong> What is multithreading, why Java needs it, what is thread safety, why thread safety is needed, state vs behavior, stale data, stack-per-thread insight, the synchronized myth.</p></li><li><p><strong>Blog 2 &#8212; The Battlefield: Heap, Stack, and Why Threads Fight Over Memory</strong> Deep dive into JVM memory model &#8212; what lives on the stack, what lives on the heap, why shared heap is the root of all concurrency problems. Visualized through story.</p></li><li><p><strong>Blog 3 &#8212; Race to Disaster: Understanding Race Conditions</strong> What is a race condition, how it happens, real-life analogies, why it is non-deterministic, why it is hard to reproduce. No fix yet &#8212; just deep understanding of the problem.</p></li><li><p><strong>Blog 4 &#8212; The Lost Update and the Stale Read: Two Bugs That Hide in Plain Sight</strong> Lost updates, stale data, visibility problems. The difference between atomicity failures and visibility failures. Why they feel like ghost bugs.</p></li><li><p><strong>Blog 5 &#8212; The Lock on the Door: Synchronized, Intrinsic Locks, and Critical Sections</strong> What synchronized means, what an intrinsic lock is, what a critical section is, synchronized method vs synchronized block, the performance trap of over-synchronization. All terms introduced and used interchangeably here.</p></li><li><p><strong>Blog 6 &#8212; The Deadlock Trap: When Threads Wait Forever</strong> What is deadlock, the four conditions that cause it, real-life story analogy, how to recognize it, how to avoid it. Livelock and starvation introduced here too.</p></li><li><p><strong>Blog 7 &#8212; Volatile: The Keyword Nobody Explains Properly</strong> CPU caches, memory visibility, what volatile guarantees, what it does not guarantee, when to use it, when not to. Common misconceptions cleared.</p></li><li><p><strong>Blog 8 &#8212; Atomic Operations: When You Need More Than Volatile</strong> What atomicity means, why volatile is not enough for compound operations, AtomicInteger, AtomicReference, compare-and-swap explained through analogy.</p></li><li><p><strong>Blog 9 &#8212; The Wait and Notify Dance: Thread Communication the Old Way</strong> wait(), notify(), notifyAll(), the producer-consumer problem, why this mechanism exists, why it is tricky to use correctly.</p></li><li><p><strong>Blog 10 &#8212; Stop Creating Threads Like Objects: The Thread Pool Philosophy</strong> Cost of raw thread creation, what a thread pool is, ExecutorService, fixed vs cached pools, why pooling is the real-world standard.</p></li><li><p><strong>Blog 11 &#8212; Callable, Future, and the Art of Getting Something Back</strong> Runnable vs Callable, what Future is, blocking with get(), timeouts, limitations of Future, real-life token analogy.</p></li><li><p><strong>Blog 12 &#8212; Locks Grown Up: ReentrantLock, ReadWriteLock, and Friends</strong> java.util.concurrent.locks, ReentrantLock vs synchronized, fairness, tryLock, ReadWriteLock for read-heavy scenarios. When to graduate from synchronized.</p></li><li><p><strong>Blog 13 &#8212; Counting Down to Action: CountDownLatch, CyclicBarrier, and Semaphore</strong> What coordination utilities are, CountDownLatch explained through story, CyclicBarrier, Semaphore, Phaser introduced. Real-world use cases for each.</p></li><li><p><strong>Blog 14 &#8212; CompletableFuture: Writing Async Code That Reads Like a Story</strong> CompletableFuture, thenApply, thenCompose, exceptionally, async pipelines, why this is the modern way to write non-blocking code.</p></li><li><p><strong>Blog 15 &#8212; The Full Mental Model: Everything You Need to Ace the Interview Room</strong> Complete recap, mental decision framework, when to use what, the most common interview questions mapped back to concepts from every blog, Gumroad-ready summary.</p></li></ul><p>Each blog builds on the last. Reading them out of order is possible. Reading them in order is better.</p><div><hr></div><h3>One Last Thing Before Blog 1</h3><p>Threading is one of those topics where partial understanding is more dangerous than no understanding.</p><p>A developer who knows nothing about threading will write single-threaded code. It will be slow. But it will be correct.</p><p>A developer who knows a little about threading will add locks and threads without a complete mental model. The code will be concurrent &#8212; and occasionally, unpredictably, silently wrong.</p><p>A developer who truly understands threading will write code that is both concurrent and correct. Not by following rules &#8212; but by understanding the system well enough to reason about it from first principles.</p><p>That third developer is who this series is trying to build.</p><p>It will take fifteen blogs. It will take patience. It will take the willingness to sit with a problem before reaching for a solution.</p><p>But at the end &#8212; you will not just know how to use Java&#8217;s concurrency tools. You will understand why they exist, what problems they solve, and exactly when and how to use them correctly.</p><p>That understanding is what separates a developer who has used concurrency from one who commands it.</p><p>Let&#8217;s begin.</p><div><hr></div><p><em>&#8212; Nitin</em></p><p><strong><a href="https://hashnode.com/@ns717">Hashnode</a></strong> <strong>|</strong> <strong><a href="https://nitinsingh717.substack.com/">Substack</a></strong> <strong>|</strong> <strong><a href="https://www.linkedin.com/in/nitinsingh717/">LinkedIn</a></strong> <strong>|</strong> <strong><a href="http://youtube.com/@nitinsingh717">Youtube</a></strong> <strong>|</strong> <strong><a href="https://www.instagram.com/ns717.dev/">Instagram</a></strong> <strong>|</strong> <strong><a href="https://github.com/ns717">GIT</a></strong> <strong>|</strong> <strong><a href="https://topmate.io/nitinsingh717/">Topmate</a></strong></p><div><hr></div><p><a href="https://open.substack.com/pub/nitinsingh717/p/the-need-why-sequential-thinking?r=dlqye&amp;utm_campaign=post&amp;utm_medium=web">Blog 1: The Need: Why Sequential Thinking Breaks the Modern World</a></p>]]></content:encoded></item><item><title><![CDATA[Blog 2: The Battlefield: Heap, Stack, and Why Threads Fight Over Memory]]></title><description><![CDATA[Why threads don&#8217;t fight over logic &#8212; they fight over data]]></description><link>https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sat, 04 Apr 2026 06:55:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Jzb-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><strong>Series:</strong> <em><a href="https://nitinsingh717.substack.com/s/threads">Thinking in Threads</a></em> | <strong>Blog:</strong> 2 <strong>|</strong> <strong>Read time:</strong> ~16 min</p></blockquote><div><hr></div><h3>1. The Battlefield You Never See</h3><p>A busy railway control room. Two signal operators, working independently at their stations.</p><p>Operator A checks the track status board &#8212; it reads &#8220;clear.&#8221; He approves Train 1 to proceed.</p><p>At the exact same moment, Operator B checks the same board &#8212; it also reads &#8220;clear.&#8221; She approves Train 2 to proceed.</p><p>Both operators followed procedure perfectly. Both read the correct status. Both made the right call &#8212; based on what they saw.</p><p>Two trains. One track. No error thrown by either operator.</p><p>Nobody made a mistake. Nobody cut corners. The system failed &#8212; because two independent workers read and acted on the same shared data simultaneously, with no coordination between them.</p><p>This is exactly what happens inside your JVM the moment two threads access the same object.</p><div><hr></div><h3>2. Pause and Ask the Right Question</h3><p>Here is a thought most developers skip past:</p><blockquote><p><em>If threads are independent workers&#8230; why do they conflict at all?</em></p></blockquote><p>The answer is not about threads. It is not about speed. It is not about scheduling.</p><p><strong>The problem is memory.</strong></p><p>Specifically &#8212; <em>where</em> your data lives, and <em>who</em> can reach it.</p><p>Shift your mental model here. Stop thinking about threads as the problem. Start thinking about <strong>memory</strong> as the battlefield. Threads are just the soldiers. The heap is where the war happens.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jzb-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jzb-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jzb-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png" width="604" height="402.80494505494505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca0706a3-4f80-4358-9295-bcc71bae87af_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:604,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!Jzb-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Jzb-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04fef395-b338-447d-8d06-a899342e94f0_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>3. Where Data Actually Lives</h3><p>When your Java program runs, the JVM carves up memory into regions. You don&#8217;t need to know all of them. You need to know two:</p><ul><li><p><strong>The Stack</strong> &#8212; private, per thread, fast</p></li><li><p><strong>The Heap</strong> &#8212; shared, global, dangerous when unprotected</p></li></ul><p>Everything else is detail. These two are the entire story of thread safety.</p><div><hr></div><h3>4. The Stack &#8212; Your Private Workspace</h3><p>Every thread in Java gets its own stack. Completely private. Completely isolated.</p><p>Think of it like a personal notepad that each worker carries. Whatever they write on it &#8212; nobody else can see it, touch it, or overwrite it.</p><p><strong>What lives on the stack:</strong></p><ul><li><p>Method calls &#8212; every time you call a method, a new frame is pushed onto the stack</p></li><li><p>Local variables &#8212; any variable declared inside a method</p></li><li><p>Return addresses &#8212; where to go after a method finishes</p></li></ul><pre><code><code>public void processPayment(int amount) {
    int tax = calculateTax(amount); // 'tax' lives on THIS thread's stack
    int total = amount + tax;       // 'total' lives on THIS thread's stack
    System.out.println(total);
    // method ends &#8594; stack frame is popped &#8594; tax and total are gone
}</code></code></pre><p><code>tax</code> and <code>total</code> are born on the stack. They die when the method ends. No other thread can see them during their entire lifetime.</p><p><strong>The insight:</strong> This is exactly why local variables are naturally <strong>thread-safe</strong>. There is no sharing happening. There is nothing to protect.</p><p>Two threads can call <code>processPayment()</code> simultaneously &#8212; each thread works on its own copy of <code>tax</code> and <code>total</code> on its own private stack. They never collide.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Zmlf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Zmlf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Zmlf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png" width="599" height="399.470467032967" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f953ef9-7735-4310-8387-27fcc3e4ce8a_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:599,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!Zmlf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Zmlf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8f54429-14f2-4116-9d7a-67da770c19b0_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>5. The Heap &#8212; The Shared Battlefield</h3><p>Now here is where everything changes.</p><p>When you create an object in Java &#8212; any object &#8212; it goes on the heap. Not your stack. Not any one thread&#8217;s private space. <strong>The shared heap. Accessible by every thread in your program.</strong></p><pre><code><code>public class BankAccount {
    private int balance; // instance variable &#8594; lives on the HEAP
    private String owner; // instance variable &#8594; lives on the HEAP
}</code></code></pre><pre><code><code>// Somewhere in your application
BankAccount account = new BankAccount(); // object created on the HEAP</code></code></pre><p><strong>What lives on the heap:</strong></p><ul><li><p>All objects you create with <code>new</code></p></li><li><p>Instance variables &#8212; the fields inside those objects</p></li><li><p>Static variables &#8212; shared across the entire application</p></li></ul><p>The moment that <code>BankAccount</code> object sits on the heap, every thread that holds a reference to it can walk in and read or modify <code>balance</code> freely.</p><p>No permission needed. No check. No warning. Just open access.</p><blockquote><p><em>This is where all concurrency problems begin. Not in your methods. Not in your logic. In the heap &#8212; the <strong>shared territory</strong> that every thread can touch.</em></p></blockquote><div><hr></div><h3>6. Why Threads Fight &#8212; Step by Step</h3><p>Let&#8217;s make this concrete. No hand-waving.</p><p>Here is a <code>BankAccount</code> with a shared <code>balance</code> on the heap:</p><pre><code><code>public class BankAccount {
    private int balance = 10000; // on the heap &#8212; shared
    
    public void deposit(int amount) {
        int current = balance;          // step 1: READ from heap
        int updated = current + amount; // step 2: COMPUTE (on stack)
        balance = updated;              // step 3: WRITE back to heap
    }
}</code></code></pre><p>Now two threads call <code>deposit()</code> simultaneously &#8212; Thread A deposits 2000, Thread B deposits 3000:</p><pre><code><code>Thread A &#8594; step 1: reads balance = 10000
Thread B &#8594; step 1: reads balance = 10000  &#8592; both read the OLD value

Thread A &#8594; step 2: computes 10000 + 2000 = 12000
Thread B &#8594; step 2: computes 10000 + 3000 = 13000

Thread A &#8594; step 3: writes balance = 12000
Thread B &#8594; step 3: writes balance = 13000  &#8592; overwrites Thread A's update
</code></code></pre><p><strong>Final balance: &#8377;13,000</strong> <strong>Correct balance: &#8377;15,000</strong> <strong>Lost forever: &#8377;2,000</strong></p><ul><li><p>What did Java throw? Nothing.</p></li><li><p>What crashed? Nothing. </p></li><li><p>What was logged? Nothing.</p></li></ul><p>Just a silently wrong number sitting in your database. This is the nature of concurrency bugs &#8212; they don&#8217;t announce themselves. They hide.</p><div><hr></div><h3>7. Thread-Local vs Shared Data</h3><p>This is the line that cuts through all confusion:</p><p><strong>Stack &#8594; thread-local &#8594; private &#8594; safe</strong><br><strong>Heap &#8594; shared &#8594; accessed by all threads &#8594; needs protection</strong></p><pre><code><code>public class PaymentProcessor {
    private int transactionCount = 0; // HEAP &#8212; shared &#8212; needs protection

    public void process(double amount) {
        double fee = amount * 0.02;   // STACK &#8212; local &#8212; already safe
        double total = amount + fee;  // STACK &#8212; local &#8212; already safe

        transactionCount++;           // HEAP &#8212; shared &#8212; danger zone
    }
}
</code></code></pre><p><code>fee</code> and <code>total</code> &#8212; born on the stack, private to this thread call, zero risk.</p><p><code>transactionCount</code> &#8212; lives on the heap, every thread touches the same variable, race condition waiting to happen.</p><blockquote><p><strong>Thread safety is only ever about shared data. Nothing else.<br></strong>If data is not shared, you don&#8217;t have a thread safety problem. Full stop.</p></blockquote><div><hr></div><h3>8. Connecting Back to Blog 1</h3><p>In Blog 1, we talked about <strong>state and behavior.</strong></p><p>Now you know exactly where each one lives:</p><ul><li><p><strong>Behavior &#8212;</strong> your methods, your logic, your algorithms.<br>These execute on the stack. Each thread gets its own execution context.<br>No sharing. No conflict.</p><p>This is why behavior alone is safe.</p></li><li><p><strong>State &#8212;</strong> your instance variables, static variables, your object fields.<br>These live on the heap and are shared across threads that access them.</p><p>This is where conflict lives.</p></li></ul><blockquote><p><em>&#8220;Threads don&#8217;t fight over logic. They fight over data.&#8221;</em></p></blockquote><p>When a thread calls a method, it is not fighting over the method itself. It is fighting over the <strong>heap data that method touches</strong>. The method is just the path that leads to the battlefield.</p><p>This single distinction &#8212; stack for execution, heap for shared state &#8212; is the foundation that every concurrency concept in this series builds on.</p><div><hr></div><h3>9. The Real Root Cause</h3><p>Let&#8217;s be precise about what the actual problem is &#8212; because most developers misdiagnose it.</p><p><strong>The problem is NOT:</strong></p><ul><li><p>Threads existing</p></li><li><p>Threads running fast</p></li><li><p>Threads being scheduled unpredictably</p></li></ul><p><strong>The problem IS:</strong></p><ul><li><p><strong>Shared mutable state</strong> sitting on the heap with no coordination around who reads and writes it</p></li></ul><p>Remove shared mutable state &#8212; the problem disappears. That is why stateless classes are always thread-safe. That is why local variables are always safe. That is why immutable objects are safe.</p><p>The thread is not your enemy. <strong>Unprotected shared state is.</strong></p><div><hr></div><h3>10. The Mistake Most Developers Make</h3><p>When developers first hit a concurrency bug, the instinct is to control the threads.</p><blockquote><p><em>&#8220;Maybe I should slow them down.&#8221;</em> <em>&#8220;Maybe I should use fewer threads.&#8221;</em> <em>&#8220;Maybe I should change the thread priority.&#8221;</em></p></blockquote><p>Wrong direction entirely.</p><p>The threads are not the problem. Trying to control threads to fix a memory problem is like rearranging traffic signals to fix a broken road. The road is what needs fixing.</p><p><strong>Control memory access &#8212; not threads.</strong></p><p>Decide who can read shared data, when, and under what conditions. That is the entire discipline of concurrent programming, distilled.</p><p>Everything &#8212; <code>synchronized</code>, <code>volatile</code>, <code>locks</code>, <code>atomic variables</code> &#8212; every tool this series will cover is ultimately a tool for <strong>controlling access to shared heap memory.</strong> Not for controlling threads.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DduG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DduG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!DduG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!DduG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!DduG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DduG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png" width="606" height="404.1387362637363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/954a9b76-d466-4ca6-b838-8931aa61e225_1536x1024.webp&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:606,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Generated image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Generated image" title="Generated image" srcset="https://substackcdn.com/image/fetch/$s_!DduG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!DduG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!DduG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!DduG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1454d143-3070-4d9f-b922-ce0a9f002a45_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p><em>&#8220;Everything still comes back to shared state.&#8221;</em></p></blockquote><p>You will see this pattern repeat across every blog in this series. Every concurrency problem, every solution, every tool &#8212; traced back to this one root: shared mutable data on the heap, accessed by multiple threads without coordination.</p><div class="pullquote"><p>Keep this line close. It will make every concept that follows immediately obvious.</p></div><h3><strong>Let&#8217;s Stay Connected</strong></h3><p>If you found this helpful, stay connected &#8212; Through <em>Level Up Your Programming with Nitin</em>, I share guides, insights, and live coding sessions to help you grow as a developer.<br>Let&#8217;s keep learning together!</p><p>Feel free to <strong>like</strong>, <strong>comment</strong>, or share your thoughts below &#8212; I&#8217;d love to hear how your Java journey is going.</p><p><em>Nitin</em><br><strong><a href="https://hashnode.com/@ns717">Hashnode</a></strong> <strong>|</strong> <strong><a href="https://nitinsingh717.substack.com/">Substack</a></strong> <strong>|</strong> <strong><a href="https://www.linkedin.com/in/nitinsingh717/">LinkedIn</a></strong> <strong>|</strong> <strong><a href="http://youtube.com/@nitinsingh717">Youtube</a></strong> <strong>|</strong> <strong><a href="https://www.instagram.com/ns717.dev/">Instagram</a></strong> <strong>|</strong> <strong><a href="https://github.com/ns717">GIT</a></strong> <strong>|</strong> <strong><a href="https://topmate.io/nitinsingh717/">Topmate</a></strong></p><p><strong><a href="https://nitinsingh717.substack.com/p/the-need-why-sequential-thinking?r=dlqye">Prev   </a>&#8212; </strong><em>The Battlefield: Heap, Stack, and Why Threads Fight Over Memory &#8212;  </em><strong>Next</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yMIN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yMIN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 424w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 848w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 1272w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yMIN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp" width="1050" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1050,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!yMIN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 424w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 848w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 1272w, https://substackcdn.com/image/fetch/$s_!yMIN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73e3217d-a98a-406e-bf04-10ca771d1972_1050x600.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Level Up Your Programming with Nitin! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Blog 1: The Need: Why Sequential Thinking Breaks the Modern World]]></title><description><![CDATA[Threads, shared state, and why your single-threaded instincts will betray you in production]]></description><link>https://nitinsingh717.substack.com/p/the-need-why-sequential-thinking</link><guid isPermaLink="false">https://nitinsingh717.substack.com/p/the-need-why-sequential-thinking</guid><dc:creator><![CDATA[Nitin Singh]]></dc:creator><pubDate>Sat, 28 Mar 2026 06:55:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iZTE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><strong>Series:</strong> <em><a href="https://nitinsingh717.substack.com/s/threads">Thinking in Threads</a></em> | <strong>Blog:</strong> 1 <strong>|</strong> <strong>Read time:</strong> ~14 min</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iZTE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iZTE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iZTE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:504922,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iZTE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!iZTE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a2adad-429b-4cdf-82bc-07338886c69e_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>TL;DR &#8212; Read This First</h3><ul><li><p>A <strong>thread</strong> is one independent path of execution. Multithreading means many paths running simultaneously.</p></li><li><p><strong>Thread safety</strong> is not about locking everything. It is about protecting shared data at the exact moment it is modified.</p></li><li><p>The real danger lives on the <strong>heap</strong> &#8212; shared objects that multiple threads can read and write at the same time.</p></li><li><p><strong>Local variables</strong> on the stack are already safe. You don&#8217;t need to protect them.</p></li><li><p>Making everything <code>synchronized</code> doesn&#8217;t make your program safer &#8212; it makes it slower. Sometimes broken in new ways.</p></li><li><p>The correct instinct is <strong>surgical, not sweeping.</strong></p></li></ul><div><hr></div><h3>You wear a helmet while riding &#8212; not bubble wrap</h3><p>You wear a helmet while riding &#8212; not because the road is dangerous every second, but because when an accident happens, your head needs to be protected at that exact moment of impact.</p><p>That is road safety. Not wrapping yourself in bubble wrap before leaving the house. Not refusing to ride at all. Just protecting the right thing, at the right moment.</p><p>Thread safety in Java works exactly the same way.</p><p>And yet, the most common advice you will hear is this:</p><blockquote><p><em>&#8220;Just add</em> <code>synchronized</code> <em>to your methods and you&#8217;re safe.&#8221;</em></p></blockquote><p>Most developers follow that advice without questioning it. Most of them don&#8217;t realize what they are actually supposed to be protecting.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t3Xg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t3Xg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t3Xg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png" width="601" height="338.0625" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:601,&quot;bytes&quot;:403772,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!t3Xg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!t3Xg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb145bcc6-8581-41d4-a7b6-4c5d195e38d9_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here is the precise rule:</p><ul><li><p>&#9989; Protect <strong>class level variables</strong> &#8212; the class-level state that lives on the heap and is shared between threads</p></li><li><p>&#9989; Protect them at the <strong>exact moment</strong> they are being modified</p></li><li><p>&#10060; Don&#8217;t protect local variables &#8212; they live on each thread&#8217;s own private stack and are already safe</p></li><li><p>&#10060; Don&#8217;t protect the entire method &#8212; methods are behavior, not data</p></li></ul><p><code>synchronized</code> is not a safety blanket. It is a surgical tool. Used in the wrong place, it doesn&#8217;t make your program safer &#8212; it makes it slower, harder to reason about, and in some cases, broken in entirely new ways.</p><p>This series is about learning to use that tool correctly.</p><div><hr></div><h3>1. First, Feel the Problem</h3><p>It is a warm afternoon. A classroom. Forty students, one teacher.</p><p>She is brilliant. She cares. She answers every question fully, then moves to the next student. One at a time. No shortcuts.</p><p>By the time she reaches student twenty-eight, the question has gone cold. Student thirty-five has already moved on &#8212; possibly with the wrong understanding. Student forty has stopped paying attention entirely.</p><p>The teacher did nothing wrong. <strong>The system failed her.</strong></p><p>One worker. Sequential flow. A world that doesn&#8217;t wait.</p><p>Sound familiar? That teacher is your Java program. Those forty students are your users. And in production, your users don&#8217;t wait politely in a queue.</p><div><hr></div><h3>2. Sequential Execution Is a Lie We Tell Beginners</h3><p>When you learn to code, you&#8217;re taught that a program runs top to bottom. One line, then the next. One method, then the next. Neat, orderly, predictable.</p><p>That model is <strong>true.</strong> It is also <strong>dangerously incomplete.</strong></p><p>It works for:</p><ul><li><p>A script that reads a file and prints a result</p></li><li><p>A utility that processes one record and exits</p></li><li><p>A hello-world program you submit for grading</p></li></ul><p>It <strong>breaks completely</strong> the moment your program has to:</p><ul><li><p>Serve ten thousand users simultaneously</p></li><li><p>Process hundreds of transactions per second</p></li><li><p>Keep a UI alive while something heavy runs in the background</p></li></ul><blockquote><p><em>Sequential execution in the real world isn&#8217;t careful &#8212; <br>it&#8217;s slow. And in production, slow is just another form of broken.</em></p></blockquote><div><hr></div><h3>3. What Multithreading Actually Is</h3><p>No jargon. Three lines:</p><ul><li><p>A <strong>thread</strong> is a single path of execution. One worker, following instructions from start to finish.</p></li><li><p>A <strong>single-threaded program</strong> has one path. One worker. Everything waits for everything else.</p></li><li><p>A <strong>multithreaded program</strong> has many paths. Many workers. Each moves forward independently.</p></li></ul><p>Think about a restaurant kitchen during dinner service. The pasta is boiling. The sauce is reducing. The garnish is being plated. Three different hands, three different tasks, all moving simultaneously. Nobody waits for anyone else to finish before they begin.</p><p><strong>That is multithreading.</strong> Your program becomes the kitchen instead of the lone cook.</p><p>Here is what that looks like in Java &#8212; the simplest possible thread creation:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;ab59547c-f28b-40b5-a08f-84234a4e5b32&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Single-threaded: everything runs on main thread
public class SingleThreaded {
    public static void main(String[] args) {
        cookPasta();   // waits to finish
        makeSauce();   // waits to finish
        plateGarnish();// waits to finish
    }
}

// Multithreaded: tasks run simultaneously
public class MultiThreaded {
    public static void main(String[] args) throws InterruptedException {
        Thread pastaThread   = new Thread(() -&gt; cookPasta());
        Thread sauceThread   = new Thread(() -&gt; makeSauce());
        Thread garnishThread = new Thread(() -&gt; plateGarnish());

        pastaThread.start();
        sauceThread.start();
        garnishThread.start();

        pastaThread.join();
        sauceThread.join();
        garnishThread.join();

        System.out.println("Dinner is served.");
    }
}</code></pre></div><p>Notice: <code>.start()</code> launches the thread. <code>.join()</code> waits for it to finish. Three workers, moving in parallel.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TiJw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TiJw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TiJw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png" width="604" height="402.80494505494505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f1d282a-1451-4fe0-933b-ff8f6f3922c8_1536x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:604,&quot;bytes&quot;:3206210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d282a-1451-4fe0-933b-ff8f6f3922c8_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TiJw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!TiJw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da2ac81-0157-4c81-a211-994ea928490f_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>4. Why Java Specifically Needs This</h3><p>Three reasons. Each more important than the last.</p><p><strong>Performance &#8212; use the hardware you already have</strong></p><ul><li><p>Your machine has multiple CPU cores. A single-threaded program uses one. The rest sit idle.</p></li><li><p>You bought an eight-burner stove and you are cooking on one flame.</p></li><li><p>A task that takes 8 seconds on one core can take ~1 second split intelligently across eight.</p></li></ul><p><strong>Responsiveness &#8212; never freeze the user again</strong></p><ul><li><p>Without multithreading, one slow operation freezes everything.</p></li><li><p>A file download freezes the UI. A database call freezes the server.</p></li><li><p>With threads, slow operations move to the background while everything stays alive.</p></li></ul><p><strong>Modern systems demand it &#8212; there is no alternative</strong></p><ul><li><p>A server handling thousands of simultaneous requests cannot queue them one at a time.</p></li><li><p>A message broker consuming events from multiple topics cannot stop and wait.</p></li><li><p>Build without concurrency and you haven&#8217;t built a slower version of the right thing. You&#8217;ve built the wrong thing.</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;dab40409-4d6d-4edc-9155-1914d09a6e2a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// Without multithreading &#8212; UI freezes during file download
public void downloadFile() {
    // This blocks the main thread. Nothing else can run.
    byte[] data = fetchFromServer(); // could take 10 seconds
    saveToFile(data);
}

// With multithreading &#8212; UI stays alive
public void downloadFileAsync() {
    new Thread(() -&gt; {
        byte[] data = fetchFromServer();
        saveToFile(data);
        System.out.println("Download complete.");
    }).start();
    // Main thread is free immediately. UI responds. User is happy.
}</code></pre></div><div><hr></div><h3>5. And Then Everything Gets Complicated</h3><p>The moment two threads need to touch the <strong>same data</strong> &#8212; the same variable, the same object, the same piece of memory &#8212; something fundamental breaks.</p><p>Not always. Not predictably. <strong>Sometimes. Randomly. Silently.</strong></p><p>And that is what makes it dangerous.</p><div><hr></div><h3>6. The Notebook Story You Won&#8217;t Forget</h3><p>Forget Java for a moment.</p><p>Priya and Arjun share a notebook. Inside it, one number &#8212; &#8377;10,000. Their joint account balance.</p><p>One afternoon:</p><ul><li><p>Priya opens the notebook. Reads &#8377;10,000. She needs to add &#8377;2,000. She does the math in her head: &#8377;12,000.</p></li><li><p>At the <strong>exact same moment</strong>, Arjun opens the same notebook. Reads &#8377;10,000. He needs to add &#8377;3,000. His math: &#8377;13,000.</p></li><li><p>Priya writes &#8377;12,000.</p></li><li><p>Arjun writes &#8377;13,000.</p></li></ul><p>One write erases the other. The notebook shows either &#8377;12,000 or &#8377;13,000 &#8212; depending purely on who wrote last.</p><p><strong>The correct answer is &#8377;15,000.</strong></p><p>Nobody made an arithmetic mistake. Nobody acted carelessly. Two workers. Same data. No coordination. One update lost forever.</p><p>Now read this Java code and notice &#8212; it is the exact same story:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;d4311bbb-f065-492f-afa7-d8186411feb4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class BankAccount {
    private int balance = 10000; // shared state &#8212; lives on the heap

    public void deposit(int amount) {
        int current = balance;       // step 1: read
        int updated = current + amount; // step 2: compute
        balance = updated;           // step 3: write
    }
}</code></pre></div><p>When Thread A (Priya, +2000) and Thread B (Arjun, +3000) call <code>deposit()</code> simultaneously:</p><pre><code><code>Thread A reads  balance = 10000
Thread B reads  balance = 10000   &#8592; both read the same old value
Thread A writes balance = 12000
Thread B writes balance = 13000   &#8592; Thread A's update is gone</code></code></pre><p>Final balance: &#8377;13,000. Lost &#8377;2,000. No exception. No stack trace. The program moves on.</p><p><strong>This is a race condition.</strong> This is why thread safety exists.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2-gM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2-gM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2-gM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png" width="607" height="404.80563186813185" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6a842ad-c9f6-4388-8f13-eed85e5b7d13_1536x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:607,&quot;bytes&quot;:2317025,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6a842ad-c9f6-4388-8f13-eed85e5b7d13_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2-gM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2-gM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97cb07f3-4dcb-47ce-89ef-532726c46de9_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>7. What Thread Safety Actually Means</h3><p>Not this: &#8220;my code has no bugs.&#8221; Not this: &#8220;my code won&#8217;t crash.&#8221;</p><p><strong>This, specifically:</strong></p><blockquote><p>Your code produces <strong>correct results</strong> even when multiple threads are running and touching shared data at the same time.</p></blockquote><p>That is the entire definition. Keep it.</p><div><hr></div><h3>8. The Trap That Kills Performance</h3><p>When developers first understand the race condition problem, the instinct is immediate &#8212; and completely wrong:</p><blockquote><p><em>&#8220;Fine. I&#8217;ll just make everything</em> <code>synchronized</code>. <em>One thread at a time. Problem solved.&#8221;</em></p></blockquote><p>This is the most common and most costly mistake in concurrent Java programming.</p><p>Here is what over-synchronization looks like:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;947bb220-bfe0-420a-a55d-33ec56e6795e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// &#10060; Wrong approach &#8212; synchronizing everything
public class BankAccount {
    private int balance = 10000;

    public synchronized int getBalance() { return balance; }
    public synchronized String getOwnerName() { return ownerName; } // doesn't touch balance!
    public synchronized void printStatement() { ... }               // read-only, no conflict!
    public synchronized void deposit(int amount) { balance += amount; }
}</code></pre></div><p><code>getOwnerName()</code> and <code>printStatement()</code> don&#8217;t touch shared mutable state. But now every thread has to <strong>queue up</strong> to call them, waiting for each other&#8217;s locks.</p><p>The result:</p><ul><li><p>You do not have a multithreaded program anymore</p></li><li><p>You have a <strong>single-threaded program</strong> with the overhead of multithreading on top</p></li><li><p>The kitchen with fifteen chefs, all forced to take turns with a single spoon</p></li></ul><p>You haven&#8217;t solved the problem. You&#8217;ve traded one failure mode for another &#8212; and this one is harder to see, because the code <em>still works</em>. It just works slowly, under load, in ways you won&#8217;t catch until production is burning.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!11Xc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!11Xc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 424w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 848w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!11Xc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png" width="604" height="483.2" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de931756-cc03-415e-9a69-d4a889b446a2_1280x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1280,&quot;resizeWidth&quot;:604,&quot;bytes&quot;:2471368,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde931756-cc03-415e-9a69-d4a889b446a2_1280x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!11Xc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 424w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 848w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!11Xc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0eeaf0bf-e660-42d2-b8af-8c8e3e892b44_1280x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>9. The Distinction That Changes Everything</h3><p>There are two things inside any Java class. Most developers treat them the same. They are not.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8a5r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8a5r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 424w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 848w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 1272w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8a5r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png" width="728" height="224.1611510791367" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:214,&quot;width&quot;:695,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:34779,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8a5r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 424w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 848w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 1272w, https://substackcdn.com/image/fetch/$s_!8a5r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82cb259d-cf87-4eb3-ae45-cc6aa64f9fdd_695x214.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Here is the most important code example in this entire blog:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;bf3fd43f-17fe-409a-8118-5ca2c2fab90b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// &#9989; Behavior only &#8212; completely thread-safe, no protection needed
public class MathUtil {
    // No instance variables. Nothing shared. Nothing to corrupt.
    public int add(int a, int b) {
        return a + b; // lives entirely on this thread's stack
    }
}

// &#9888;&#65039; State + Behavior &#8212; the deposit method touches shared state
public class BankAccount {
    private int balance; // instance variable = shared state = danger zone

    public void deposit(int amount) {
        balance += amount; // reading AND writing shared state &#8212; needs protection
    }

    public int getBalance() {
        return balance; // reading shared state &#8212; may need protection depending on context
    }
}</code></pre></div><p><code>MathUtil.add()</code> can be called from a million threads simultaneously. Safe. Zero conflict. Each thread does its own math and leaves.</p><p><code>BankAccount.deposit()</code> called from multiple threads simultaneously without protection? Corrupted balance. Silent. No error thrown.</p><p><strong>The method isn&#8217;t the problem. The shared state inside it is.</strong></p><p>So your question should never be:</p><blockquote><p><em>&#8220;Is this method thread-safe?&#8221;</em></p></blockquote><p>Your question should be:</p><blockquote><p><em>&#8220;Does this method touch shared state &#8212; and if so, is that access protected?&#8221;</em></p></blockquote><div><hr></div><h3>10. Why the Heap Makes This Unavoidable</h3><p>Every thread in Java has its own <strong>call stack</strong> &#8212; a private scratchpad for:</p><ul><li><p>Local variables</p></li><li><p>Method call history</p></li><li><p>Return addresses</p></li></ul><p>Completely private. Thread A cannot see Thread B&#8217;s stack. <strong>No conflict possible there.</strong></p><p>But every thread shares the same <strong>heap</strong>. The heap is where objects live. When you create a <code>BankAccount</code>, a <code>UserSession</code>, a <code>ShoppingCart</code> &#8212; those objects sit on the heap. Every thread that holds a reference to that object can read and modify it freely.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;4eaec214-e08a-433c-834c-5136315df339&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(10000); // lives on the HEAP

        Thread priya = new Thread(() -&gt; account.deposit(2000)); // both threads
        Thread arjun = new Thread(() -&gt; account.deposit(3000)); // share same object

        priya.start();
        arjun.start();
    }
}</code></pre></div><p>Here is the exact setup for disaster:</p><ol><li><p>Thread A reads <code>balance</code> from the shared object on the heap &#8594; sees 10,000</p></li><li><p>Before it finishes computing and writes back &#8594; Thread B reads the same <code>balance</code> &#8594; also sees 10,000</p></li><li><p>Both compute their update. Both write back.</p></li><li><p>One write erases the other. Data is wrong.</p></li><li><p>No error is thrown. The program moves on.</p></li></ol><p><strong>The heap is shared territory.</strong> Without coordination at the right moments, it quietly breaks.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tTDt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tTDt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tTDt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a111f3b-b47e-47f0-876c-035348eda899_1536x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1063265,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nitinsingh717.substack.com/i/191749532?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a111f3b-b47e-47f0-876c-035348eda899_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tTDt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!tTDt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F565eb60b-eb4c-40e4-b680-1a7834215937_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>11. Protect the Modification &#8212; Not the Method</h3><p>This is the correct mental model. Read it slowly.</p><p>You don&#8217;t need to protect your entire methods. You need to protect the <strong>specific moment when shared state is being read and then modified</strong> as one uninterrupted sequence.</p><p>Think of a shared whiteboard in an office:</p><ul><li><p>Multiple people can <strong>read</strong> it simultaneously &#8212; no problem</p></li><li><p>The conflict only happens when someone <strong>picks up a marker</strong></p></li><li><p>That moment &#8212; reading and rewriting together &#8212; is what needs protection</p></li></ul><p>In Java, that narrow region of code is called the <strong>critical section.</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;1a873a83-5040-4037-a192-55e3e8c2f4c7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">public class BankAccount {
    private int balance;
    private final Object lock = new Object();

    public void deposit(int amount) {
        // Non-critical: pure logic, no shared state touched
        validateAmount(amount);
        logDepositAttempt(amount);

        // &#9989; Critical section &#8212; protect only this
        synchronized (lock) {
            balance += amount; // read + modify + write = must be atomic
        }

        // Non-critical: this runs freely in parallel
        sendDepositNotification(amount);
    }
}</code></pre></div><p>Notice what is <strong>outside</strong> the <code>synchronized</code> block:</p><ul><li><p><code>validateAmount()</code> &#8212; pure logic, no shared state</p></li><li><p><code>logDepositAttempt()</code> &#8212; can run in parallel safely</p></li><li><p><code>sendDepositNotification()</code> &#8212; no shared data touched</p></li></ul><p><strong>Only the actual modification is protected.</strong> Everything else runs free. That is where your performance lives.</p><p>Protect the critical section. Not the whole method. Not every line. Just the place where shared state changes.</p><div><hr></div><h3>12. One Special Case: The Stateless Class</h3><p>Here is something most developers never stop to think about:</p><blockquote><p><strong>A stateless object is always thread-safe. Always.</strong></p></blockquote><p>A class with no instance variables &#8212; nothing to store, no shared data &#8212; can be called by a thousand threads simultaneously and nothing will ever go wrong. Because there is nothing shared to corrupt.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;java&quot;,&quot;nodeId&quot;:&quot;289d3cff-34d0-4ea2-ae9f-82c51b2f2e5d&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-java">// &#9989; Always thread-safe &#8212; no instance variables, no shared state
public class TaxCalculator {
    public double calculate(double income, double rate) {
        return income * rate; // everything lives on this thread's stack
    }
}

// &#9989; Typical Servlet &#8212; stateless, always thread-safe
public class PaymentServlet extends HttpServlet {
    // No instance variables here = no shared state = no thread safety concern
    protected void doPost(HttpServletRequest req, HttpServletResponse res) {
        String amount = req.getParameter("amount"); // local variable = stack = safe
        processPayment(amount);
    }
}</code></pre></div><p>A thousand HTTP requests hit <code>PaymentServlet</code> simultaneously. Each thread runs <code>doPost()</code> with its own local variables on its own stack. Zero conflict. Zero synchronization needed.</p><p>The moment you add an instance variable to that Servlet &#8212; a counter, a cache, a shared list &#8212; you have introduced shared state. And now you have a thread safety problem to solve.</p><div><hr></div><h3>13. Before You Move On &#8212; Hold These Three Thoughts</h3><ol><li><p> Multithreading is not optional in modern Java. It is the difference between software that scales and software that collapses under load.</p></li><li><p>Thread safety is not about locking everything. It is about identifying shared state and protecting the exact moment it is modified &#8212; nothing more, nothing less.</p></li><li><p>The biggest trap is not ignoring thread safety. The biggest trap is <strong>over-protecting</strong> it &#8212; turning a concurrent program back into a sequential one wearing a disguise.</p></li></ol><blockquote><p>The correct instinct is surgical, not sweeping. Find the shared state. Find the modification. Protect that. Let everything else breathe.</p></blockquote><p><em>If this was useful, share it with one developer who still thinks</em> <code>synchronized</code> <em>on every method is fine. It might save them a production incident</em></p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Level Up Your Programming with Nitin&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Level Up Your Programming with Nitin</span></a></p><div><hr></div><blockquote><p><em>If this was useful, consider sharing it with someone who&#8217;s on the same journey.</em></p></blockquote><p>I write every week about <strong>System Design</strong>, <strong>Java Backend Engineering</strong>, <strong>Distributed Systems</strong>, and <strong>Developer Career Growth</strong> &#8212; the stuff that actually matters for growing from fresher to senior engineer.</p><p><strong>[Subscribe now]</strong> &#8212; it&#8217;s free, and you can unsubscribe anytime.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://nitinsingh717.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://nitinsingh717.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Let&#8217;s keep learning together. &#128640;</p><p>If you have questions, a topic you&#8217;d like me to cover, or just want to share how your journey is going &#8212; drop a comment below. I read every one.</p><div><hr></div><p><strong>Find me here:</strong> <a href="https://claude.ai/chat/your-link">LinkedIn</a> &#183; <a href="https://claude.ai/chat/your-link">YouTube</a> &#183; <a href="https://claude.ai/chat/your-link">Instagram</a> &#183; <a href="https://claude.ai/chat/your-link">GitHub</a> &#183; <a href="https://claude.ai/chat/your-link">Hashnode</a> &#183; <a href="https://claude.ai/chat/your-link">Topmate</a></p><p><strong><a href="https://nitinsingh717.substack.com/publish/post/194174249?r=dlqye&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true">Prev</a>    </strong><em>The Need: Why Sequential Thinking Breaks the Modern World</em><strong>     <a href="https://nitinsingh717.substack.com/p/the-battlefield-heap-stack-and-why?r=dlqye">Next</a></strong></p>]]></content:encoded></item></channel></rss>