Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8342068

Implement JEP 502: Stable Values (Preview)

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 25
    • core-libs
    • None
    • source
    • minimal
    • This is a new API.
    • Java API
    • SE

      Summary

      Introduce an API for stable values, which are objects that hold immutable data. Stable values are treated as constants by the JVM, enabling the same performance optimizations that are enabled by declaring a field final. Compared to final fields, however, stable values offer greater flexibility as to the timing of their initialization.

      This CSR refers to the first iteration of the Stable Value API to make the API available as a Preview API.

      Problem

      There is a tension between final immutable fields and their mutable counterparts. Immutable fields must be initialized exactly once in the constructor or static initializer and can enjoy constant folding. Mutable fields can change at any time over and over again and hence, cannot be trusted by the VM to not change. There are a number of attempted workarounds using double-checked locking, concurrent maps, etc. but none of them provides constant folding.

      Solution

      Introduce the Stable Values API, which adds support for stable values. Stable values can be initialized from anywhere in the code, by any thread, and at any time. Yet, if set, they can be constant-folded. A stable value is an immutable holder of content of type T.

      The StableValue interface contains six methods:

      • trySet(T t) returns true if the content was set to t or false if the content was already set
      • setOrThrow(T t) sets the content to t, otherwise throws an exception if the content was already set
      • orElse(T t)returns the content (if set), otherwise returns t
      • orThrow() returns the content (if set), otherwise throws NoSuchElementException
      • isSet() returns if the content is set.
      • orElseSet(Supplier<? extends T> s) returns the content, otherwise computes a value using s and initializes the content accordingly (which is then returned)

      The StableValue interface also contains seven static factories:

      • StableValue.of(), creates a new unset StableValue with no content.
      • StableValue.of(T value), creates a new set StableValue with the provided content.
      • StableValue.supplier(Supplier<? extends T> s), creates a Supplier<T> that caches the value of s (the latter is invoked at most once) in an internal StableValue
      • StableValue.intFunction(int size, IntFunction<? extends R> m) creates an IntFunction<R> with allowed [0..size) inputs that caches the values produced by m in an internal array of StableValue elements
      • StableValue.function(Set<T> inputs, Function<T, R> m) creates a Function<T, R> with allowed inputs that caches the values produced by m in an internal array of StableValue elements.
      • StableValue.list(int size, IntFunction<? extends R> m). Similar to intFunction() but returns a completely lazy List<R>.
      • StableValue.map(Set<T> inputs, Function<T, R> m). Similar to function() but returns a completely lazy Map<T, R>.

      Specification

      See attachment sv-diff4.txt. For convenience, there is an HTML archive of the StableValue docs attached as well ( HTML4)

        1. StableValue_HTML.zip
          695 kB
        2. StableValues_HTML4.zip
          695 kB
        3. sv-diff.txt
          24 kB
        4. sv-diff2.txt
          27 kB
        5. sv-diff3.txt
          26 kB
        6. sv-diff4.txt
          28 kB

            pminborg Per-Ake Minborg
            pminborg Per-Ake Minborg
            Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: