语言规范中的Java静态初始化线程安全性保证 [英] Java static initialization thread safety guarantee in language spec

查看:71
本文介绍了语言规范中的Java静态初始化线程安全性保证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

普遍认为静态初始化是线程安全的.保证只发生一次.但是我很好奇,在语言规范中它确切指出在可见性方面会有问题吗? 这来自 http://www.ibm.com/developerworks/library/j-jtp03304 /

It is commonly accepted that static initialization is thread safe. It is guaranteed to only happen once. I am however curious exactly where in the language spec does it state that there will be on visibility problems? This comes from http://www.ibm.com/developerworks/library/j-jtp03304/

此过程保证,当变量在给定监视器保护的同步块中由一个线程写入,并在同一监视器保护的同步块中由另一线程读取时,变量的写入将通过读取可见线.在没有同步的情况下,JMM不会做出此保证

This process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread. The JMM does not make this guarantee in the absence of synchronization

我从其他一些来源也读过类似的文章.在静态初始化的情况下,我们不使用任何同步.假设已初始化的资源实际上是不可变的,并且我们从不对其进行写入,那么将永远不会有用于访问它的同步并且也不会使它不稳定.那么,保证读取线程不会看到空指针或部分初始化的对象的地方又在哪里呢?显然,由于它是在加载期间发生的,因此另一个线程不可能先读取该值并看到一个过时的值,但是什么能保证初始化的结果不会保留在执行线程的本地内存中呢?我很想知道静态初始化是安全的原因.

I have read similar things from a few other sources. In case of static initialization we do not use any synchronization. Assuming the initialized resource is effectively immutable, and we never write to it, there will be no synchronization used to access it ever and do not make it volatile. So where does the guarantee come from that any reading thread will not see a null pointer or partially initialized object? Obviously, since it happens during loading there is no possibility that another thread read the value before and sees a stale value, but what guarantees that results of the initialization do not stay in executing thread's local memory? Im curious to read the reason static initialization is safe.

我知道静态初始化是线程安全的.问题是为什么,什么能保证?

I understand static initialization is thread safe. Question is why and what guarantees that.

推荐答案

我认为这实际上是 JLS 17.4.4 (我认为-我不是这方面的专家).

I believe this is effectively a result of the rules for class initialization in JLS 12.4.2. That involves synchronizing on a lock, only releasing it after executing the static initializers and field initializers. That lock acquisition and release then affects the "happens before" part of the thread model, via JLS 17.4.4 (I think - I'm not an expert on this).

请注意12.4.2声明:

Note that 12.4.2 states:

如果实现可以确定类的初始化已经完成,则实现可以通过在步骤1中取消锁获取(并在步骤4/5中释放)来优化此过程,但前提是就内存模型而言,如果获得了锁,则所有先于排序都将存在,但在执行优化时仍然存在.

An implementation may optimize this procedure by eliding the lock acquisition in step 1 (and release in step 4/5) when it can determine that the initialization of the class has already completed, provided that, in terms of the memory model, all happens-before orderings that would exist if the lock were acquired, still exist when the optimization is performed.

这篇关于语言规范中的Java静态初始化线程安全性保证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆