Skip to content

Commit 42ebfc0

Browse files
authored
Merge pull request #6 from mcimadamore/patch-1
Update StableValue.java
2 parents 905af97 + 09ae146 commit 42ebfc0

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

src/java.base/share/classes/java/lang/StableValue.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,19 @@
4545
* <p>
4646
* A {@linkplain StableValue {@code StableValue<T>}} is created using the factory method
4747
* {@linkplain StableValue#empty() {@code StableValue.empty()}}. When created, the
48-
* stable value is <em>unset</em>, which means it holds no value. It's holder value of
49-
* type {@code T} can be <em>set</em> by passing a value via
48+
* stable value is <em>unset</em>, which means it holds no value. Its holder value, of
49+
* type {@code T}, can be <em>set</em> by calling
5050
* {@linkplain #trySet(Object) trySet()}, {@linkplain #setOrThrow(Object) setOrThrow()},
51-
* or {@linkplain #computeIfUnset(Supplier) computeIfUnset()}. Once set, the value held
52-
* by a {@code StableValue} can never change and can be retrieved by calling
51+
* or {@linkplain #computeIfUnset(Supplier) computeIfUnset()}. Once set, the holder value
52+
* can never change and can be retrieved by calling
5353
* {@linkplain #orElseThrow() orElseThrow()}, {@linkplain #orElse(Object) orElse()}, or
5454
* {@linkplain #computeIfUnset(Supplier) computeIfUnset()}.
5555
* <p>
56-
* A stable value that is <em>set</em> is treated as a constant by the JVM, enabling
57-
* the same performance optimizations that are possible by marking a field {@code final}.
58-
* Yet, stable values offer greater flexibility as to the timing of initialization
56+
* A stable value that is <em>set</em> is treated as a constant by the JVM, enabling the
57+
* same performance optimizations that are available for {@code final} fields.
58+
* As such, stable values can be used to replace {@code final} fields in cases where
59+
* <em>at-most-once</em> update semantics is crucial, but where the eager initialization semantics
60+
* associated with {@code final} fields is too restrictive.
5961
* <p>
6062
* Consider the following example where a stable value field "{@code logger}" is an
6163
* immutable holder of a value of type {@code Logger} and that is initially created
@@ -86,10 +88,9 @@
8688
* <p>
8789
* Note that the holder value can only be set at most once.
8890
* <p>
89-
* To guarantee that only one instance of {@code Logger} instance is ever created, the
90-
* {@linkplain #computeIfUnset(Supplier) computeIfUnset()} method can be used instead as
91-
* shown in this improved example, where the holder is atomically and lazily computed via
92-
* a lambda expression:
91+
* To guarantee that, even under races, only one instance of {@code Logger} is ever created, the
92+
* {@linkplain #computeIfUnset(Supplier) computeIfUnset()} method can be used instead,
93+
* where the holder is atomically and lazily computed via a lambda expression:
9394
*
9495
* {@snippet lang = java:
9596
* class Component {
@@ -115,8 +116,6 @@
115116
* returned to the client. In other words, {@code computeIfUnset()} guarantees that a
116117
* stable value's holder value is <em>set</em> before it is used.
117118
* <p>
118-
* Even though the stable value, once <em>set</em>, is immutable, its holder value is not
119-
* required to be <em>set</em> upfront. Rather, it can be <em>set</em> on demand.
120119
* Furthermore, {@code computeIfUnset()} guarantees that the lambda expression provided is
121120
* evaluated only once, even when {@code logger.computeIfUnset()} is invoked concurrently.
122121
* This property is crucial as evaluation of the lambda expression may have side effects,
@@ -126,8 +125,8 @@
126125
* <h2 id="stable-functions">Stable Functions</h2>
127126
* Stable values provide the foundation for higher-level functional abstractions. A
128127
* <em>stable supplier</em> is a supplier that computes a value and then caches it into
129-
* a backing stable value storage for later use. A stable supplier is created -- via the
130-
* {@linkplain StableValue#ofSupplier(Supplier) StableValue.ofSupplier()} factory --
128+
* a backing stable value storage for later use. A stable supplier is created via the
129+
* {@linkplain StableValue#ofSupplier(Supplier) StableValue.ofSupplier()} factory,
131130
* by providing an original {@linkplain Supplier} which is invoked when the
132131
* stable supplier is first accessed:
133132
*
@@ -144,14 +143,15 @@
144143
* }
145144
* }
146145
*}
147-
* This also allows the stable supplier to be accessed directly, without going through
148-
* an accessor method like {@code getLogger()} in the previous example.
146+
* A stable supplier encapsulates access to its backing stable value storage. This means that
147+
* code inside {@code Component} can obtain the logger object directly from the stable supplier,
148+
* without having to go through an accessor method like {@code getLogger()}.
149149
* <p>
150150
* A <em>stable int function</em> is a function that takes an {@code int} parameter and
151151
* uses it to compute a result that is then cached into the backing stable value storage
152-
* for that parameter value. When the stable int function is first created -- via the
152+
* for that parameter value. A stable int function is created via the
153153
* {@linkplain StableValue#ofIntFunction(int, IntFunction) StableValue.ofIntFunction()}
154-
* factory -- the input range (i.e. [0, size)) is specified together with an original
154+
* factory. Upon creation, the input range (i.e. [0, size)) is specified together with an original
155155
* {@linkplain IntFunction} which is invoked at most once per input value. In effect,
156156
* the stable int function will act like a cache for the original {@linkplain IntFunction}:
157157
*
@@ -171,9 +171,9 @@
171171
* <p>
172172
* A <em>stable function</em> is a function that takes a parameter (of type {@code T}) and
173173
* uses it to compute a result that is then cached into the backing stable value storage
174-
* for that parameter value. When the stable function is first created -- via the
175-
* {@linkplain StableValue#ofFunction(Set, Function) StableValue.ofFunction()} factory --
176-
* the input {@linkplain Set} is specified together with an original {@linkplain Function}
174+
* for that parameter value. A stable function is created via the
175+
* {@linkplain StableValue#ofFunction(Set, Function) StableValue.ofFunction()} factory.
176+
* Upon creation, the input {@linkplain Set} is specified together with an original {@linkplain Function}
177177
* which is invoked at most once per input value. In effect, the stable function will act
178178
* like a cache for the original {@linkplain Function}:
179179
*
@@ -193,7 +193,7 @@
193193
*
194194
* <h2 id="stable-collections">Stable Collections</h2>
195195
* Stable values can also be used as backing storage for immutable collections.
196-
* A <em>stable list</em> is an immutable list of fixed size, backed by an array of
196+
* A <em>stable list</em> is an immutable list, backed by an array of
197197
* stable values. The stable list elements are computed when they are first accessed,
198198
* using a provided {@linkplain IntFunction}:
199199
*
@@ -233,9 +233,9 @@
233233
* }
234234
*}
235235
* <h2 id="thread-safety">Thread Safety</h2>
236-
* A holder value is guaranteed to only be settable at most once. If competing threads are
237-
* racing to set a holder value, only the first is accepted and the other threads are
238-
* blocked until the holder value is set.
236+
* A holder value is guaranteed to be set at most once. If competing threads are
237+
* racing to set a stable value, only one update succeeds, while other updates are
238+
* blocked until the stable value becomes set.
239239
* <p>
240240
* Updates to an object
241241
* <a href="{@docRoot}/java.base/java/util/concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>

0 commit comments

Comments
 (0)