darkapple
darkapple

Reputation: 549

Java concurrency confusion

I've following class

class A{

private int id =0;
   public void setMessageId(Message m) {
      synchronized(m) {
        m.setId(id++);
      }
   }
}

Can two threads with same instance of class A with DIFFERENT instances of Message enter into the synchronized block at same time and set same id to different instances of message?

Upvotes: 0

Views: 105

Answers (7)

Mikko Maunu
Mikko Maunu

Reputation: 42074

Yes, because they both have locks to different objects.

One option without self made synchronization at all is to use AtomicInteger:

class A{
    private final AtomicInteger id = new AtomicInteger();

    public void setMessageId(Message m) {
       m.setId(id.incrementAndGet());    
    }
}

Method incrementAndGet incerements value by one and returns updated value.

Upvotes: 0

fmucar
fmucar

Reputation: 14548

Yes:

The lock object is obtained for the m object which are 2 different objects for each of your threads so yes they can. You will need to obtain a lock which is shared between those 2 and that A class in your case.

Upvotes: 0

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33534

1. As the synchronized lock is on the instance of message, and then two thread with different message object can definately access this block at the same time.

2. Even if they are setting the same instance variable, its like a personal copy which is one per object.

3. Thread changing the variable id of one object will Not effect the id of other object.

Upvotes: 0

mishadoff
mishadoff

Reputation: 10789

Sure, because you synchronize on different objects.

If all what you need for this purpose it's ID generation better to use java.util.concurrent AtomicInteger.

For example like this:

private AtomicInteger counter;

public int getNextUniqueIndex() {
    return counter.getAndIncrement();
}

Upvotes: 0

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70931

If you only synchronize on m, then two objects will be able to modify the same instance of A. You need to synchronize on the object that stores the value id.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691635

Yes. Since the block is synchronized on the message, two threads using two different message instances can enter the synchronized block concurrently, and both get the same ID.

Make the method synchronized, and everything will be fine. Or use an AtomicInteger.

Upvotes: 2

Nim
Nim

Reputation: 33655

Yes. You need to synchronize on the object that holds the id field (in this case 'A') or some common object.

Upvotes: 3

Related Questions