RFR: 8351565: Implement JEP 502: Stable Values (Preview) [v6]
John Rose
john.r.rose at oracle.com
Sun Mar 16 03:29:28 UTC 2025
A @Stable field does not need to be volatile.
Avoiding volatile is one of the uses for @Stable.
That said, @Stable is not as foolproof as volatile.
It’s more dangerous, and cheaper.
You have to do a release store to a stable variable.
That’s what the VM does for you automatically for
a final, and a stable is like a delayed final.
But the VM does not give you the release store
automatically; you must do it manually.
That’s why @Stable is an internal feature, and
StableValue is the “housebroken” version of it.
StableValue has to help the VM maintain the
appearance of a “final” variable whose initialization
got delayed. The wrapAndSet method does this job.
This might seem to contradict my previous assertion
that StableValue, being mutex based, must not
use lock-free idioms. That comment applies
specifically to the update operation that takes
a lambda. Other operations, such as reading
a SV, or hopefully poking a value at a SV can be,
and should be, composed of lock-free operations.
Why take a lock when it’s just a one-word read
or write?
On 13 Mar 2025, at 9:07, Maurizio Cimadamore wrote:
> On Thu, 13 Mar 2025 15:22:43 GMT, Per Minborg <pminborg at openjdk.org> wrote:
>
>>> Implement JEP 502.
>>>
>>> The PR passes tier1-tier3 tests.
>>
>> Per Minborg has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 246 commits:
>>
>> - Merge branch 'master' into implement-jep502
>> - Clean up exception messages and fix comments
>> - Rename field
>> - Rename method and fix comment
>> - Rework reenterant logic
>> - Use acquire semantics for reading rather than volatile semantics
>> - Add missing null check
>> - Simplify handling of sentinel, wrap, and unwrap
>> - Fix JavaDoc issues
>> - Fix members in StableEnumFunction
>> - ... and 236 more: https://git.openjdk.org/jdk/compare/4e51a8c9...d6e1573f
>
> src/java.base/share/classes/jdk/internal/lang/stable/StableValueImpl.java line 74:
>
>> 72: @Override
>> 73: public boolean trySet(T value) {
>> 74: if (wrappedContentAcquire() != null) {
>
> IMHO, if our goal is to do:
>
> Object content = this.content;
> if (context != null) return content:
> synchronized (...) {
> if (context != null) return content:
> this.context = ...
> }
>
>
> Then we might just use a volatile field and synchronized blocks. I don't see an immediate need for using acquire/release semantics --
> especially when using a monitor. E.g. this should look more like a classic double checked locking idiom. (but with a stable field to make the first volatile read more efficient in case the field is already set)
>
> -------------
>
> PR Review Comment: https://git.openjdk.org/jdk/pull/23972#discussion_r1993850760
More information about the core-libs-dev
mailing list