1
votes

1) if synchronized(this) is used, which means that any of the two threads will lock on factor instance and increment val variable value till the loop exits. so synchronized(this) means here that we should not use any other instance variables. We have to use only the variables of factor instance inside the synchronized block?

2) if synchronized(addition) means here that we have to use only add variable not the val variable of factor instance class?

There is a big confusion regarding this synchronization block . what i understood is synchronization block will lock on the object's instance and guard the operation and make it thread safe. But using different instance really means that it should guard only that particular instance variables not any other instance variables. Can anyone explain in depth concept regarding this relating with the code provided below

class Factor implements Runnable
{
 int val = 0;
Addition addtion = new Addition();

@Override
public void run()
{

    currInsLock();
    diffInsLock();
}

// locking on the current instance which is this
// we will use synchronized(this)

public void currInsLock() 
{
    synchronized (this) 
    {
        for(int i=0;i<100;i++)
        {
                try
                  {
                     Thread.sleep(100);
                  }
                catch (InterruptedException e)
                {
                      e.printStackTrace();
                }   
        System.out.println(Thread.currentThread().getName()+"---val value lock on this obj -->"+val++);

        }
    }
}



// locking on the different instance
public void diffInsLock() 
{
    synchronized (addtion) 
    {

        for(int i=0;i<100;i++)
        {
                try
                  {
                     Thread.sleep(100);
                  }
                catch (InterruptedException e)
                {
                      e.printStackTrace();
                }   
        System.out.println(Thread.currentThread().getName()+"---val value lock on addition obj -->"+val++);
        System.out.println(Thread.currentThread().getName()+"---add value lock on addition obj -->"+addtion.add++);
        }
    }
}

}

Addition class :

public class Addition  
{
   public int add=0;
}

The Main class

 public class ConcurrentDoubt {

 public static void main(String[] args)
{
  Factor factor=new Factor();

  Thread thread1=new Thread(factor);
  Thread thread2=new Thread(factor);

   thread1.start();
   thread2.start();

}
}
1

1 Answers

2
votes

What you use as object's monitor is not really important, it could be any object, I would even say that ideally we should never use this as object's monitor but rather a private final Object instance to better protect our class because if outside your code, we use the instance of your class as object's monitor it could prevent your class to work properly.

The key point is to use exact same object's monitor anytime you want to modify or access to anything that you want to protect (member variables, class instances...) if what you want to protect is accessed/modified outside a synchronized block or with a different object's monitor, your code is no more thread-safe because you don't prevent concurrent accesses or modifications anymore. Indeed only one thread can execute code protected by a synchronized block for a given object's monitor, so it you have 2 different object's monitors to protect the same thing, you could have 2 threads accessing/modifying what you try to protect.

So here, you use this and addtion as object's monitors to protect your member variable val so your code is not thread-safe, you need to use the same object's monitor.

Assuming that you want to use this as object's monitor to protect your member variable val, your code should rather be:

synchronized (addtion) {
    for(int i=0;i<100;i++) {
        ...
        synchronized (this) {
            System.out.println(
                Thread.currentThread().getName() + 
                "---val value lock on addition obj -->" + val++
            );
        }
        System.out.println(
            Thread.currentThread().getName() + 
            "---add value lock on addition obj -->" + addtion.add++
        );
    }
}