问题
This is my Java 1.6 class:
public class Foo {
private ArrayList<String> names;
public void scan() {
if (names == null) {
synchronized (this) {
this.names = new ArrayList<String>();
// fill the array with data
}
}
}
}
Findbugs says:
Inconsistent synchronization of com.XXX.Foo.names; locked 40% of time
What does it mean and what I'm doing wrong? I'm trying to avoid problems when two or more clients call Foo.scan()
at the same time.
回答1:
It's beacuse you are only synchronizing when you set the names
variable and not when you read it. So between the read and the write another thread could execute and you'd create two ArrayLists and fill them with data, the first one created would get GC'ed.
You need to put the synchronized block around the read and the write or add the synchronized modifier to the method.
public class Foo {
private ArrayList<String> names;
public void scan() {
synchronized (this)
if (names == null) {
this.names = new ArrayList<String>();
// fill the array with data
}
}
}
}
回答2:
The first time you reference names
inside scan
is outside of synchronized
block.
E.g., if scan
is called twice from two different threads and names
is null, it may go like this
if (names == null)
from the first thread is processed (totrue
).if (names == null)
from the second thread is processed (totrue
).- First thread enters
synchronized
block, assignesnames
and leavessynchronized
block. - Second thread enters
synchronized
block, assignesnames
and leavessynchronized
block.
Now, names
is initialized twice. And this is only one possible scenario where you get unexpected results.
来源:https://stackoverflow.com/questions/4187286/what-inconsistent-synchronization-means