简体   繁体   English

这个java类线程安全吗? 并发读写

[英]Is this java class thread safe? Concurrent read and write

Is the following class thread safe? 以下类线程是否安全? I am worrying about concurrent read and write the initialized variable. 我担心并发读取和写入初始化变量。 If it is not thread safe, how to make it thread safe? 如果它不是线程安全的,如何使其线程安全?

  1. I know convert methodA to synchronized will help, but I don't want to do this 我知道将methodA转换为synchronized会有所帮助,但我不想这样做
  2. How about add volatile keywork to "initialized" variable? 如何将volatile volatile keywork添加到“initialized”变量?
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: The initialized variable will only be modified once in init method, all other methods will only ready. Update1:​​初始化变量只在init方法中修改一次,所有其他方法只准备好。 If that is the case, adding volatile to initialized will make it thread safe, is that correct? 如果是这种情况,将volatile添加到初始化将使其线程安全,这是正确的吗?

No, it is not thread safe. 不,它不是线程安全的。 The init routine could be in the middle of setting initialized when methodA is called. 调用methodA时, init例程可能处于initialized设置的中间。 Since methodA is not synchronized, there's nothing preventing a race between executing initialized = true and the read in if( !initialized) . 由于methodA不同步,因此没有什么能阻止执行initialized = true和read in if( !initialized)之间的竞争。 In fact, the write could even have happened but simply not yet propagated to the thread that called methodA 事实上,写入甚至可能已经发生但尚未传播到调用methodA的线程

Adding volatile to initialized would help with the value propagation problem, but not with the first. volatile添加到initialized将有助于值传播问题,但不会与第一个有关。

For more info on this, I recommend Brian Goetz's article Managing Volatility . 有关这方面的更多信息,我推荐Brian Goetz的文章Managing Volatility

No its not thread safe. 不,它不是线程安全的。 you have to syncronize. 你必须同步。

@HotLicks is 100% correct. @HotLicks 100%正确。 Any question regarding concurrency needs to provide context. 有关并发的任何问题都需要提供上下文。 Here's why: 原因如下:

Let's assume a class has been written to be "safe" (ignoring the OPs class for the moment). 让我们假设一个类已被编写为“安全”(暂时忽略OP类)。 If you are synchronizing on an instance variable and the instance of the class is shared by many threads, then it will be thread-safe. 如果要在实例变量上进行同步,并且该类的实例由许多线程共享,那么它将是线程安全的。 However, if multiple instances of the class can be created (by the different threads), and they potentially modify static variables/state, then it will only be thread-safe if you synchronize on a static (ie class) variable. 但是,如果可以创建类的多个实例(由不同的线程),并且它们可能修改静态变量/ state,那么只有在静态(即类)变量上进行同步时,它才是线程安全的。

In summary: 综上所述:

  1. If sharing single instance between threads, then lock on instance variable 如果在线程之间共享单个实例,则锁定实例变量
  2. If threads are creating instances of the "safe" class AND static state is potentially modified by those threads, then must lock on static (class) variable 如果线程正在创建“安全”类的实例并且静态状态可能被这些线程修改,那么必须锁定静态(类)变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM