Why Using synchronized on a Local Variable Fails to Lock in Java Multithreading
The article demonstrates that synchronizing on a locally created object does not provide proper thread safety, shows the resulting chaotic output, and explains how moving the lock object to a class field resolves the issue, illustrated with Java code and debugging screenshots.
During a code review the author discovered a Java senior engineer mistakenly used synchronized on a locally created object, believing it would protect shared data across threads.
The original program creates two threads that both execute MyThread.run(), where a new Object is instantiated inside the method and used as the monitor:
package com.sample.interview.multithread;
public class SynchronizedTest {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread t1 = new Thread(myThread, "线程1");
Thread t2 = new Thread(myThread, "线程2");
t1.start();
t2.start();
}
}
class MyThread implements Runnable {
private static int count = 0;
@Override
public void run() {
Object obj = new Object();
synchronized (obj) {
for (int i = 0; i < 3; i++) {
System.out.println("当前线程:" + Thread.currentThread().getName() + ",数值为:" + (count++));
}
}
}
}Because each thread creates its own obj, the two monitors are different, so the synchronized block does not serialize the execution. The sample output shows interleaved prints from both threads, e.g.:
当前线程:线程2,数值为:1
当前线程:线程1,数值为:0
当前线程:线程2,数值为:2
当前线程:线程1,数值为:3
当前线程:线程2,数值为:4
当前线程:线程1,数值为:5The article then modifies the code by making the lock object a class‑level static field (instead of a local variable). After this change the output becomes ordered, confirming that the threads now contend for the same monitor:
当前线程:线程1,数值为:0
当前线程:线程1,数值为:1
当前线程:线程1,数值为:2
当前线程:线程2,数值为:3
当前线程:线程2,数值为:4
当前线程:线程2,数值为:5Debugging screenshots illustrate the thread states: one thread is RUNNING while the other is in the MONITOR (blocked) state, waiting for the lock to be released. The conclusion is that synchronizing on a local variable does not provide mutual exclusion; the lock must be a shared object, typically a field, to be effective.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
