Fundamentals 9 min read

Understanding Java's synchronized(this) Object Lock and Thread Interaction

This article explains how Java's synchronized(this) keyword creates an object lock that allows only one thread to execute a synchronized block at a time, demonstrates various scenarios with code examples, and shows how non‑synchronized sections remain concurrent while all synchronized sections on the same object are blocked.

Java Captain
Java Captain
Java Captain
Understanding Java's synchronized(this) Object Lock and Thread Interaction

Java's synchronized keyword, when used to guard a method or a code block (e.g., synchronized(this) ), ensures that at most one thread can execute that section of code at any given moment by acquiring the object's monitor lock.

Example 1: Two concurrent threads invoke a synchronized(this) block on the same object. The output shows that thread A completes all iterations before thread B starts.

package ths;

public class Thread1 implements Runnable {
    public void run() {
        synchronized(this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
            }
        }
    }
    public static void main(String[] args) {
        Thread1 t1 = new Thread1();
        Thread ta = new Thread(t1, "A");
        Thread tb = new Thread(t1, "B");
        ta.start();
        tb.start();
    }
}

Result:

A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4

Example 2: While one thread holds the object lock inside a synchronized block, another thread can still execute non‑synchronized code of the same object, resulting in interleaved output.

package ths;

public class Thread2 {
    public void m4t1() {
        synchronized(this) {
            int i = 5;
            while(i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try { Thread.sleep(500); } catch (InterruptedException ie) {}
            }
        }
    }
    public void m4t2() {
        int i = 5;
        while(i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try { Thread.sleep(500); } catch (InterruptedException ie) {}
        }
    }
    public static void main(String[] args) {
        final Thread2 myt2 = new Thread2();
        Thread t1 = new Thread(() -> myt2.m4t1(), "t1");
        Thread t2 = new Thread(() -> myt2.m4t2(), "t2");
        t1.start();
        t2.start();
    }
}

Result (interleaved):

t1 : 4
t2 : 4
t1 : 3
t2 : 3
t1 : 2
t2 : 2
t1 : 1
t2 : 1
t1 : 0
t2 : 0

Example 3: If the second method is also wrapped in a synchronized block on the same object, the second thread must wait until the first releases the lock, producing sequential output.

public void m4t2() {
    synchronized(this) {
        int i = 5;
        while(i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try { Thread.sleep(500); } catch (InterruptedException ie) {}
        }
    }
}

Result:

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0

Example 4: Declaring the method as synchronized yields the same blocking behavior because the method acquires the object's monitor.

public synchronized void m4t2() {
    int i = 5;
    while(i-- > 0) {
        System.out.println(Thread.currentThread().getName() + " : " + i);
        try { Thread.sleep(500); } catch (InterruptedException ie) {}
    }
}

Result is identical to Example 3.

Example 5: The lock applies to any synchronized block or method that uses the same object. An inner class demonstrates that a synchronized block on an Inner instance blocks other synchronized sections on that same instance, while non‑synchronized code runs concurrently.

package ths;

public class Thread3 {
    class Inner {
        private void m4t1() {
            int i = 5;
            while(i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
                try { Thread.sleep(500); } catch (InterruptedException ie) {}
            }
        }
        private void m4t2() {
            int i = 5;
            while(i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
                try { Thread.sleep(500); } catch (InterruptedException ie) {}
            }
        }
    }
    private void m4t1(Inner inner) {
        synchronized(inner) { // object lock
            inner.m4t1();
        }
    }
    private void m4t2(Inner inner) {
        inner.m4t2();
    }
    public static void main(String[] args) {
        final Thread3 myt3 = new Thread3();
        final Inner inner = myt3.new Inner();
        Thread t1 = new Thread(() -> myt3.m4t1(inner), "t1");
        Thread t2 = new Thread(() -> myt3.m4t2(inner), "t2");
        t1.start();
        t2.start();
    }
}

Result shows that t1 acquires the lock on inner , so t2 's call to m4t2 (which is not synchronized) proceeds without waiting, demonstrating that only synchronized sections are blocked.

In summary, acquiring an object lock via synchronized(this) or a synchronized method blocks all other synchronized blocks or methods on the same object, while code that is not synchronized can still execute concurrently.

JavaconcurrencySynchronizationmultithreadingobject lock
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.