我已经声明了一个枚举,这就是它的样子(不是真正的代码)
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()并使用工厂。 通过从输入流中读取文件来创建工厂。
用例是我需要以编程方式刷新此工厂。
问题:
有没有办法锁定工厂的访问权限直到它更新?那会有多乱?
可以简单地更新工厂而不进行任何锁定。这样做的含义是什么?
答案 0 :(得分:2)
有没有办法锁定工厂的访问权限直到它更新?那会有多乱?
您可以将getMyFactory
和loadFactory
同步。
可以简单地更新工厂而不进行任何锁定。这样做的含义是什么?
您需要将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()
中不需要其他同步。