1

Two classes factor and addition

factor is having val variable that means it is shared across multiple threads (in the current application we are using two threads).

addition class is having a add variable it is also shared across multiple threads, because it's instantiated in factor class.

my question is

  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?

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++);
        }
    }
}

}

Class Action & ConcurrentDoubt:

public class Addition  
{
    public int add=0;

}

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();

}
}
Aditya W
  • 652
  • 8
  • 20
amt14779
  • 125
  • 1
  • 1
  • 5

2 Answers2

1

No. Synchronizing on a specific object doesn't lock that object, and doesn't prevent you from using other objects inside the synchronized block.

Synchronizing on an object prevents another thread also trying to synchronize on the same object to enter the synchronized block until the first thread has exited from its synchronized block. It's up to you to decide how you synchronize access to some mutable state. It could be the object containing that state, or any other object. The important thing is that all threads accessing this mutable state use the same object to synchronize.

In the posted code, the addtion.add mutable state is properly guarded, because all threads synchronize on the same object, addtion, to access it.

The val mutable state is not properly guarded, because one method synchronizes on this to access it, and the other synchronizes on addtion. So if one thread calls the first methods while another one calls the second, they will both try to increment and read the same value concurrently.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • According to the answer provided that synchronization(addition) is correct because addition,add mutable state is properly guarded. The val mutable state is not properly guarded because the increment operation is used in synchronization(addition), which means the val variable is accessed in synchronization(addition). if i used val variable only inside synchronization(this) and add variable only inside synchronization(addition) will both the variables guarded properly but what is the difference – amt14779 Oct 02 '16 at 11:31
0

For better understanding of synchronization concepts, read oracle tutorial articles of synchronized methods and intrinsic locks

synchronized` keyword is applicable for methods/code blocks and not for variables.

synchronized(this) means here that we should not use any other instance variables.

That's wrong. synchronized(this) allows access to one of threads and keeps other treads in waiting. But at the same time, the member variables object can be modified by other methods.

Method 1: You acquired lock synchronized (this) but you did not modify member variable : addition. You can have some other methods , which can modify member variables (both addition and val) of Factor object.

Method 2: You have acquired lock with synchronized (addtion). Now addition can't be modified by other thread, trying to access addition variable from this code block. You have used wrong addition to modify val since other threads can freely modify val variable (which is primitive and not an object).

If you want to protect a variable (of type object) synchronize that particular variable instead of entire object.

Define fine granular locks in your application.

But using different instance really means that it should guard only that particular instance variables not any other instance variables?

synchronized make sure that : It is not possible for two invocations of synchronized methods on the same object to interleave. But if you have difference instances and these instances can modify data independently unless the variable is static and methods are static synchronized

Have a look at related SE questions:

What does 'synchronized' mean?

Synchronization vs Lock

Avoid synchronized(this) in Java?

Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211