这个java类是线程安全的吗?并发读写
下面的类是线程安全的吗?我担心并发读写初始化变量。如果它不是线程安全的,如何使其线程安全这个java类是线程安全的吗?并发读写,java,concurrency,Java,Concurrency,下面的类是线程安全的吗?我担心并发读写初始化变量。如果它不是线程安全的,如何使其线程安全 我知道将methodA转换为synchronized会有帮助,但我不想这样做 将volatile keywork添加到“initialized”变量中如何 更新1: 初始化的变量在init方法中只修改一次,所有其他方法只准备就绪。如果是这种情况,将volatile添加到initialized将使其成为线程安全的,对吗?不,它不是线程安全的。 init < /Cord>例程可以设置在初始化 > 方法> < /
初始化的变量在init方法中只修改一次,所有其他方法只准备就绪。如果是这种情况,将volatile添加到initialized将使其成为线程安全的,对吗?不,它不是线程安全的。<代码> init < /Cord>例程可以设置在<代码>初始化 > <代码>方法> < /C> >。由于
methodA
未同步,因此执行initialized=true
与读取if(!initialized)
之间没有任何冲突。事实上,写操作甚至可能已经发生,但还没有传播到调用methodA
将volatile
添加到initialized
将有助于解决值传播问题,但对第一个问题没有帮助
关于这方面的更多信息,我推荐Brian Goetz的文章。不,它不是线程安全的。
您必须同步。@HotLicks是100%正确的。关于并发性的任何问题都需要提供上下文。原因如下: 让我们假设一个类被编写为“安全的”(暂时忽略OPs类)。如果在实例变量上进行同步,并且该类的实例由多个线程共享,那么它将是线程安全的。但是,如果可以(由不同的线程)创建类的多个实例,并且它们可能修改静态变量/状态,那么只有在对静态(即类)变量进行同步时,它才是线程安全的 总之:
该类肯定不是线程安全的,使
初始化变量volatile
不会使其线程安全。问题是,你能接受吗?如果你的程序在initialized
为false
时确实抛出了一个异常,并且没有执行任何其他操作,那么答案可能是“是的,在使initialized
变量volatile
”之后。在使用上下文之外询问这些方法是否“安全”是毫无意义的。@dasblinkenlight,是的,methodA将抛出异常。如果initialized是volatile,我认为它应该是线程safe@performanceuser我想问题是:如果init已经在运行但还没有完成,methodA抛出异常可以吗?如果可以,那么volatile就是您所需要的。如果没有,那么您需要描述当init已启动但尚未完成时methodA将要做什么。@performanceuser它不会是线程安全的,但后果将非常轻微,您可以安全地忽略这一事实。如果我将volatile添加到initialized中,为什么它直到现在都不是线程安全的?你能解释一下吗?@performanceuser-如果init()
对initialized
所做的一切都是在开始时测试它,然后在结束时写入它,那么方法本身就不需要同步,你可以使用volatile
。(如果可以从多个线程调用init()
本身,那么它仍然需要同步。)我链接到的Goetz文章中非常详细地描述了用于此分析的确切因素。
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()
}
}
}