【发布时间】:2018-05-30 17:17:04
【问题描述】:
我有大量使用静态变量的线程,该变量在同步块中延迟初始化。初始化是内存密集型的,因此理想情况下只想这样做一次。我知道线程访问他们自己缓存的静态变量副本,但它需要一些时间才能被缓存,所以最初每个线程都进入初始化块。即使它是同步的,这也可能导致内存不足错误。
有没有办法强制静态变量在第一个线程初始化后立即可供所有新线程使用?
代码(简化):
class TestingThread extends Thread {
private static Templates transformTemplateRequest = null;
private static final Object lockObj = new Object();
private Document xslt;
public void run() {
//Document xslt initialized
Transformer requestTransformer = null;
synchronized (lockObj) {
if (transformTemplateRequest == null) {
TransformerFactory tf = TransformerFactory.newInstance();
Source xsltSource = new DOMSource(xslt);
transformTemplateRequest = tf.newTemplates(xsltSource);
}
}
requestTransformer = transformTemplateRequest.newTransformer();
//other work
}
}
【问题讨论】:
-
如果保证你需要这个对象,那么延迟初始化有什么好处呢?为什么不创建变量
final,并在创建任何线程之前在static块中对其进行初始化? -
我会将 transformTemplateRequest 保留在 AtomicReference 中,并使用单独的线程对其进行初始化。然后任何其他线程都可以检查该值并在不为空时使用它。
-
您正在尝试重新发明惰性线程安全的单例。只需检查一下 Java 中的一些线程安全实现即可:en.wikipedia.org/wiki/Double-checked_locking
-
谢谢 - 静态初始化器是个好主意,但它被添加到一个非常大的现有应用程序中 - 代码 sn-p 被简化,并且在加载类时可能无法满足依赖关系.
-
“即使它是同步的,这也可能导致内存不足错误。”不可以。显示的代码只允许单个线程初始化
transformTemplateRequest。一旦该线程退出synchronized块,任何其他线程都会看到分配给transformTemplateRequest的非空值
标签: java multithreading