Reputation: 1013
I am trying to understand a part of code which involves synchronizing on an object and one of the synchronized blocks changes some fields of the object. The code I am looking at is similar to the following:
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(someObject) {
//change some field of someObject
}
}
public void FuncB() {
synchronized(someObject) {
//change some field of someObject
}
}
}
Is this a safe practice to do? I have read a few pages online describing the safe practices for the locks but none seem to deal with a similar example.
Any help is appreciated. Thanks!
Upvotes: 0
Views: 393
Reputation: 131316
You have multiple ways to synchronize the access to a method.
One appears better than another according to the synchronization requirement.
Is this a safe practice to do?
It is a safe practice if it is used for a use case that suits.
Here the synchronization makes sense as it locks on someObject
which the two methods perform modifications on them.
Yes you could synchronize on this
or synchronize the whole methods such as :
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(this) {
//change some field of someObject
}
}
public void FuncB() {
synchronized(this) {
//change some field of someObject
}
}
}
but these would lock the whole object while this may not be required.
Upvotes: 1
Reputation: 9928
Yes this is safe. someObject
is private so only FuncA
and FuncB
have access to it. They both synchronize on someObject
so only 1 of the methods at a time will execute on someObject
even if from different running threads.
Note that it is important that all methods of ClassA
that want to access someObject
should do so within synchronized
on someObject
to avoid any risk of reading or writing inconsistent state into someObject
(unless you understand exactly what you are doing!).
Upvotes: 1
Reputation: 140309
Yes, that's fine.
For example, this is basically what you (can) do when writing to an ArrayList
from multiple threads: you synchronized on the list, and update its fields (the internal array, size etc).
The caveat is that you mustn't also access the someObject
in a non-synchronized way anywhere.
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(someObject) {
//change some field of someObject
}
}
// ...
// BAD! Don't do this.
public void FuncC() {
// read some field of someObject
}
}
Upvotes: 1