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.
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
}
}
}
}
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 (to true).if (names == null) from the second thread is processed (to true).synchronized block, assignes names and leaves synchronized block.synchronized block, assignes names and leaves synchronized block.Now, names is initialized twice. And this is only one possible scenario where you get unexpected results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With