锁定与直接更新

时间:2014-05-06 02:37:06

标签: java concurrency thread-safety

我已经声明了一个枚举,这就是它的样子(不是真正的代码)

public enum MySession {

    INSTANCE;

    MySession() {
        loadFactory();
    }

    public void refreshMyFactory() {
        //Is it OK to call "loadFactory" here as-is, or should I worry about concurrency
    }

    private void loadFactory() {
        MyFactory factory = null;
        try {
            //Initialize factory by doing some IO.
        } catch (final Exception exception) {
            //Handle Exception
        } finally {
            myFactory = factory;
            //If NULL, log FATAL exception...
        }
    }

    private MyFactory myFactory;

    /**
     * @return the sessionFactory
     */
    public MyFactory getMyFactory() {
        return myFactory;
    }

}

有多个线程可以访问MySession.INSTANCE.getMyFactory()并使用工厂。 通过从输入流中读取文件来创建工厂。

用例是我需要以编程方式刷新此工厂。

问题:

有没有办法锁定工厂的访问权限直到它更新?那会有多乱?

可以简单地更新工厂而不进行任何锁定。这样做的含义是什么?

2 个答案:

答案 0 :(得分:2)

  

有没有办法锁定工厂的访问权限直到它更新?那会有多乱?

您可以将getMyFactoryloadFactory同步。

  

可以简单地更新工厂而不进行任何锁定。这样做的含义是什么?

您需要将myFactory设置为volatile以确保可以看到更改。这意味着您不需要任何其他操作来保证线程安全。即对于您拥有的代码,罚款。

答案 1 :(得分:0)

替换以下代码段:

private void loadFactory() {
    ...
    myFactory = factory;
}
private MyFactory myFactory;
public MyFactory getMyFactory() {
    return myFactory;
}

使用:

private void loadFactory() {
    ...
    myFactoryRef.set(factory);
}
private AtomicReference<MyFactory> myFactoryRef;
public MyFactory getMyFactory() {
    return myFactoryRef.get();
}

您无需担心任何其他同步。 atomic reference确保对变量的更新是原子的。 因此,调用getMyFactory()的其他线程将查看旧实例或MyFactory的新实例,loadFactory()refreshMyFactory()中不需要其他同步。