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