以下类线程是否安全?我担心并发读取和写入初始化变量。如果它不是线程安全的,如何使其线程安全?
public class A {
private boolean initialized;
public synchronized void init(String configFilePath) {
if (initialized) {
return;
}
initialized = true;
}
public void methodA() {
if (!initialized) {
throw new ConfigurationException()
}
}
}
UPDATE1: 初始化变量只能在init方法中修改一次,所有其他方法只能准备好。如果是这种情况,将volatile添加到初始化将使其线程安全,这是正确的吗?
答案 0 :(得分:3)
不,它不是线程安全的。调用init
时,initialized
例程可能正在设置methodA
。由于methodA
未同步,因此无法阻止执行initialized = true
和if( !initialized)
中的读取之间的竞争。实际上,写入甚至可能已经发生但尚未传播到调用methodA
将volatile
添加到initialized
会有助于价值传播问题,但不会与第一个问题有关。
有关此内容的更多信息,我推荐Brian Goetz的文章Managing Volatility。
答案 1 :(得分:0)
不,它不是线程安全的。 你必须同步。
答案 2 :(得分:0)
@HotLicks 100%正确。有关并发的任何问题都需要提供上下文。原因如下:
让我们假设一个类已被编写为“安全”(暂时忽略OP类)。如果要在实例变量上进行同步,并且该类的实例由许多线程共享,那么它将是线程安全的。但是,如果可以创建类的多个实例(由不同的线程),并且它们可能修改静态变量/状态,那么只有在静态(即类)变量上进行同步时,它才是线程安全的。
总结: