yeg*_*256 7 java synchronization
这是我的Java 1.6类:
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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Findbugs说:
Inconsistent synchronization of com.XXX.Foo.names; locked 40% of time
Run Code Online (Sandbox Code Playgroud)
这是什么意思,我做错了什么?当两个或多个客户端同时呼叫Foo.scan()时,我试图避免出现问题.
bra*_*ain 18
您只是在设置names变量时才进行同步,而不是在读取变量时进行同步.因此,在读取和写入之间,另一个线程可以执行,并且您将创建两个ArrayLists并用数据填充它们,第一个创建的将获得GC.
您需要将同步块放在读取和写入周围,或者将synchronized修饰符添加到方法中.
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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
第一次引用names内部scan是在synchronized块之外.
例如,如果scan从两个不同的线程调用两次并且names为null,则它可能是这样的
if (names == null)从第一个线程处理(到true).if (names == null)从第二个线程处理(到true).synchronized块,分配names和离开synchronized块.synchronized块,分配names和离开synchronized块.现在,names初始化两次.这只是一种可能出现意外结果的可能情况.