Reputation: 549
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
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
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
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
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
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
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
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