Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutithreading Synchronization

Synchronization works well with the below code.

  public class Main implements Runnable {
    public static void main(String[] args) {
        Main m = new Main();
        for (int i = 0; i < 2; i++) {
            Thread t = new Thread(m);
            t.start();
        }
    }

    @Override
    public void run() {
        synchronized(this) {
            for (int i = 0; i < 500; i++) {
                System.out.println(i);
            }
        }
    }
 }

 // Synchronization isn't working here.

 public class Main implements Runnable {
    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            Thread t = new Thread(new Main());
            t.start();
        }
    }

    @Override
    public void run() {
        synchronized(this) {
            for (int i = 0; i < 500; i++) {
                System.out.println(i);
            }
        }
    }
 }

This question was asked in an interview. I was a bit confused about this so I'm trying to understand why synchronization isn't working with the second code snippet. Can anybody explain me why synchronization won't work with the second code snippet ?

like image 845
KarthickN Avatar asked Feb 23 '26 04:02

KarthickN


2 Answers

Because synchronization is applied for if you are working on single object.

In first case you have single runnable object of Main i.e. m

In second case you have independent objects of Main.

for(int i=0;i<2;i++){
    Thread t = new Thread(new Main()); // independent objects for each thread
    t.start();
}

Explaination:

If you see the code you will find below line

synchronized (this) {

this refers to the object itself. So lock is applied based on this object. So in case of multiple Main class object they work independently where as in single object synchronization is applied for that object only.


For more information refer : Intrinsic Locks and Synchronization

Code from the documentation

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void inc1() {
        synchronized(lock1) { // lock is acquired using lock1 object 
            c1++;
        }
    }

    public void inc2() {
        synchronized(lock2) { // lock is acquired using lock1 object 
            c2++;
        }
    }
}

In this example you can call both the methods inc1() and inc2() using single object at same time because lock is acquired on different objects. This will help you understand it better.

So in your case lock is acquired on this(object itself). So whenever you have multiple object then it will work independently and when you have single object then it will work synchronously.

like image 114
Naman Gala Avatar answered Feb 25 '26 18:02

Naman Gala


You are creating two objects here.

synchronized(this) block will synchronize access to the same object if multiple threads try to access it.

like image 26
Sumit Trehan Avatar answered Feb 25 '26 17:02

Sumit Trehan