Java 确保所有线程立即缓存静态变量
我有大量使用静态变量的线程,静态变量在同步块中延迟初始化。初始化是内存密集型的,因此理想情况下,我们希望只执行一次。我知道线程访问它们自己的静态变量缓存副本,但是在缓存之前需要一些时间,所以最初每个线程都会进入初始化块。即使是同步的,也可能导致内存不足错误 有没有办法强制静态变量在第一个线程初始化后立即对所有新线程可用 代码(简化):Java 确保所有线程立即缓存静态变量,java,multithreading,Java,Multithreading,我有大量使用静态变量的线程,静态变量在同步块中延迟初始化。初始化是内存密集型的,因此理想情况下,我们希望只执行一次。我知道线程访问它们自己的静态变量缓存副本,但是在缓存之前需要一些时间,所以最初每个线程都会进入初始化块。即使是同步的,也可能导致内存不足错误 有没有办法强制静态变量在第一个线程初始化后立即对所有新线程可用 代码(简化): 如果stmt: if (transformTemplateRequest == null) { synchronized (lockObj) {
如果stmt:
if (transformTemplateRequest == null) {
synchronized (lockObj) {
if (transformTemplateRequest == null) {
TransformerFactory tf = TransformerFactory.newInstance();
Source xsltSource = new DOMSource(xslt);
transformTemplateRequest = tf.newTemplates(xsltSource);
}
}
}
如果已经设置了变量,则完全绕过同步块。如果保证需要对象,那么延迟初始化有什么好处?为什么不在创建任何线程之前将变量
final
,并在静态
块中对其进行初始化?我会将transformTemplateRequest保留在原子引用中,并使用单独的线程对其进行初始化。然后,任何其他线程都可以检查该值,如果该值不为null,则可以使用它。您正在尝试重新创建懒惰的线程安全单例。只需检查Java中的一些线程安全实现:谢谢-静态初始值设定项是一个好主意,但是它被添加到一个非常大的现有应用程序中-代码片段被简化,并且在加载类时可能不满足一些依赖项。“即使它是同步的,这也可能导致内存不足错误。”否。显示的代码仅允许单个线程初始化transformTemplateRequest
。一旦该线程退出synchronized
块,如果transformTemplateRequest
未标记为volatile
,则任何其他线程都将看到分配给transformTemplateRequest的非空值。此代码可能会导致问题:谢谢,双重检查听起来正是我要查找的。没有意识到这种模式-将transformTemplateRequest
标记为volatile是一个很好的链接和优点。
if (transformTemplateRequest == null) {
synchronized (lockObj) {
if (transformTemplateRequest == null) {
TransformerFactory tf = TransformerFactory.newInstance();
Source xsltSource = new DOMSource(xslt);
transformTemplateRequest = tf.newTemplates(xsltSource);
}
}
}