Reputation: 151
Consider following code, I want to make it a thread safe class, so that it will never get odd number:
class Test {
private int value = 0;
private final Object lock;
public void add() {
synchronized (lock) {
value++;
value++;
}
}
public int getValue() {
synchronized (lock) {
return value;
}
}
}
I am now doubt of the lock field, which is declared to be final, will this matter? or it will break the thread safety?
I think if the lock field is not declared to be final, this should be a thread-safe class. If this conclusion is wrong, please correct me, thank you.
Upvotes: 5
Views: 750
Reputation: 19037
When you're trying to synchronize multiple threads, they have to be synchronized based on the same object reference/instance. This ensures that they both synchronize at the same time based on the same data.
Hope that makes a bit of sense; you just have to synchronize based on a finalized variable rather than a dynamic one.
If a method modifies a static field, you must synchronize access to this field, even if the method is typically used only by a single thread. It is not possible for clients to perform external synchronization on such a method because there can be no guarantee that unrelated clients will do likewise, see.
Upvotes: 0
Reputation: 115
If you're looking to lock an instance, then final is acceptable. Should you look to lock or put a mutex on a class, then make the variable static.
Upvotes: 1
Reputation: 966
You can use the ReadWriteLock to achieve the same result and with a safe implementation.
References:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html
http://www.javapractices.com/topic/TopicAction.do?Id=118
Upvotes: 1
Reputation: 13196
Should be ok. might even make it safer, since one cannot simply assign something else to the lock during execution.
Upvotes: 1
Reputation: 4445
In Java the synchonization is done by some hidden field of the lock object. Also final means, that the REFERENCE is final, not the object itself.
Example:
final Bar bar = new Bar(); //bar hase property lock
bar.lock = XYZ; //will work, object is not FINAL
bar = new Bar(); //fail, the reference is FINAL
Upvotes: 0
Reputation: 533780
I am now doubt of the lock field, which is declared to be final, will this matter?
Yes, its considered best practice to only lock final
field objects.
If you can change the reference you can change which object is locked, breaking thread safety.
Upvotes: 9