了解线程安全

时间:2017-05-07 22:13:54

标签: java multithreading

我试图了解这是否是线程安全的。我相信它是,但最近有人质疑这种方法的线程安全性。

让我们说我有一些工厂FactoryA给我们一个实现以下界面的类:

public abstract class MyFactory {
    private ObjectA object;
    public void init(ObjectA object){
        _object = object;
    }
}

所以,我们有类似

的东西
public class FactoryA extends MyFactory {
    static final createFactoryClass(String name) {
        // ...ignorning safety checks for brevity
        return MY_MAP.get(name).newInstance();
    }
}

现在,我在另一个类中有一些方法可以获取工厂并返回可能类的映射:

public class OtherClass {
    private static FactoryA _factory = new FactoryA();
    private static final Map<String, SomeClass> MY_MAP = new ImmutableMap.Builder<String, MyClass>()
    .put("foo", _factory.createFactoryClass("foo"));

    private SomeObject myMethod(ObjectA objectA, SomeObject someObject) {
        MY_MAP.get(someObject.getString()).init(objectA);
    }
}

问题是init方法是否是线程安全的。映射只初始化一次,因此即使它存储在不可变结构中,如果两个线程使用不同的ObjectA调用它,错误的类是否可能使用错误的ObjectA

我可以通过执行以下操作来解决此问题吗?

private static synchronized myMethod(...) {}

1 个答案:

答案 0 :(得分:-1)

我建议对类/方法进行不同的命名,因为目前很难理解发生了什么。我也会把工厂变成单身人士。

import java.util.HashMap;
import java.util.Map;


public class FactoryStore {

private static final Map<String, AbstractFactory> FACTORIES = new HashMap<>();

static {
    FACTORIES.put("a", FactoryA.getInstance());
    FACTORIES.put("b", FactoryB.getInstance());
}

public static Object createObject(String factoryName, Object parameters) {
    return FACTORIES.get(factoryName).createNewObject(parameters);
}
}



 abstract class AbstractFactory {

Object createNewObject(Object parameters) {
    // not thread-safe stuff
    return new Object();
}


 }



class FactoryA extends AbstractFactory {

private static final FactoryA instance = new FactoryA();

private FactoryA() {
    // thread safe stuff
}

public static FactoryA getInstance() {
    return instance;
}


 }


 class FactoryB extends AbstractFactory {

private static final FactoryB instance = new FactoryB();

 private FactoryB() {
    // thread safe stuff
}

public static FactoryB getInstance() {
    return instance;
}

@Override
synchronized Object createNewObject(Object obj) {
     // can override object creation; this is thread-safe thanks to keyword
    return new Object();
}

 }