58 | * This method will be invoked within the first thread that accesses 59 | * the value with the {@link #get get} method. 60 | *
61 | * Normally, this method is invoked at most once per class, 62 | * but it may be invoked again if there has been a call to 63 | * {@link #remove remove}. 64 | *
65 | * If this method throws an exception, the corresponding call to {@code get} 66 | * will terminate abnormally with that exception, and no class value will be recorded. 67 | * 68 | * @param type the type whose class value must be computed 69 | * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface 70 | * @see #get 71 | * @see #remove 72 | */ 73 | protected abstract T computeValue(Class> type); 74 | 75 | /** 76 | * Returns the value for the given class. 77 | * If no value has yet been computed, it is obtained by 78 | * an invocation of the {@link #computeValue computeValue} method. 79 | *
80 | * The actual installation of the value on the class 81 | * is performed atomically. 82 | * At that point, if several racing threads have 83 | * computed values, one is chosen, and returned to 84 | * all the racing threads. 85 | *
86 | * The {@code type} parameter is typically a class, but it may be any type, 87 | * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}. 88 | *
89 | * In the absence of {@code remove} calls, a class value has a simple
90 | * state diagram: uninitialized and initialized.
91 | * When {@code remove} calls are made,
92 | * the rules for value observation are more complex.
93 | * See the documentation for {@link #remove remove} for more information.
94 | *
95 | * @param type the type whose class value must be computed or retrieved
96 | * @return the current value associated with this {@code ClassValue}, for the given class or interface
97 | * @throws NullPointerException if the argument is null
98 | * @see #remove
99 | * @see #computeValue
100 | */
101 | public T get(Class> type) {
102 | // non-racing this.hashCodeForCache : final int
103 | ClassValue.Entry>[] cache;
104 | ClassValue.Entry
127 | * In order to explain the interaction between {@code get} and {@code remove} calls,
128 | * we must model the state transitions of a class value to take into account
129 | * the alternation between uninitialized and initialized states.
130 | * To do this, number these states sequentially from zero, and note that
131 | * uninitialized (or removed) states are numbered with even numbers,
132 | * while initialized (or re-initialized) states have odd numbers.
133 | *
134 | * When a thread {@code T} removes a class value in state {@code 2N},
135 | * nothing happens, since the class value is already uninitialized.
136 | * Otherwise, the state is advanced atomically to {@code 2N+1}.
137 | *
138 | * When a thread {@code T} queries a class value in state {@code 2N},
139 | * the thread first attempts to initialize the class value to state {@code 2N+1}
140 | * by invoking {@code computeValue} and installing the resulting value.
141 | *
142 | * When {@code T} attempts to install the newly computed value,
143 | * if the state is still at {@code 2N}, the class value will be initialized
144 | * with the computed value, advancing it to state {@code 2N+1}.
145 | *
146 | * Otherwise, whether the new state is even or odd,
147 | * {@code T} will discard the newly computed value
148 | * and retry the {@code get} operation.
149 | *
150 | * Discarding and retrying is an important proviso,
151 | * since otherwise {@code T} could potentially install
152 | * a disastrously stale value. For example:
153 | *
283 | * All user-visible state changes on the ClassValue take place under
284 | * a lock inside the synchronized methods of ClassValueMap.
285 | * Readers (of ClassValue.get) are notified of such state changes
286 | * when this.version is bumped to a new token.
287 | * This variable must be volatile so that an unsynchronized reader
288 | * will receive the notification without delay.
289 | *
290 | * If version were not volatile, one thread T1 could persistently hold onto
291 | * a stale value this.value == V1, while while another thread T2 advances
292 | * (under a lock) to this.value == V2. This will typically be harmless,
293 | * but if T1 and T2 interact causally via some other channel, such that
294 | * T1's further actions are constrained (in the JMM) to happen after
295 | * the V2 event, then T1's observation of V1 will be an error.
296 | *
297 | * The practical effect of making this.version be volatile is that it cannot
298 | * be hoisted out of a loop (by an optimizing JIT) or otherwise cached.
299 | * Some machines may also require a barrier instruction to execute
300 | * before this.version.
301 | */
302 | private volatile Version
154 | *
164 | * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
165 | * observe the time-dependent states as it computes {@code V1}, etc.
166 | * This does not remove the threat of a stale value, since there is a window of time
167 | * between the return of {@code computeValue} in {@code T} and the installation
168 | * of the the new value. No user synchronization is possible during this time.
169 | *
170 | * @param type the type whose class value must be removed
171 | * @throws NullPointerException if the argument is null
172 | */
173 | public void remove(Class> type) {
174 | ClassValueMap map = getMap(type);
175 | map.removeEntry(this);
176 | }
177 |
178 | // Possible functionality for JSR 292 MR 1
179 | /*public*/ void put(Class> type, T value) {
180 | ClassValueMap map = getMap(type);
181 | map.changeEntry(this, value);
182 | }
183 |
184 | /// --------
185 | /// Implementation...
186 | /// --------
187 |
188 | /** Return the cache, if it exists, else a dummy empty cache. */
189 | private static ClassValue.Entry>[] getCacheCarefully(Class> type) {
190 | // racing type.classValueMap{.cacheArray} : null => new ClassValue.Entry[X] <=> new ClassValue.Entry[Y]
191 | ClassValueMap map = classValueMap.get(type);
192 | if (map == null) return EMPTY_CACHE;
193 | ClassValue.Entry>[] cache = map.getCache();
194 | return cache;
195 | // invariant: returned value is safe to dereference and check for an ClassValue.Entry
196 | }
197 |
198 | /** Initial, one-element, empty cache used by all Class instances. Must never be filled. */
199 | private static final ClassValue.Entry>[] EMPTY_CACHE = { null };
200 |
201 | /**
202 | * Slow tail of ClassValue.get to retry at nearby locations in the cache,
203 | * or take a slow lock and check the hash table.
204 | * Called only if the first probe was empty or a collision.
205 | * This is a separate method, so compilers can process it independently.
206 | */
207 | private T getFromBackup(ClassValue.Entry>[] cache, Class> type) {
208 | ClassValue.Entry
316 | *
320 | * Promises are never put into the cache; they only live in the
321 | * backing map while a computeValue call is in flight.
322 | * Once an entry goes stale, it can be reset at any time
323 | * into the dead state.
324 | */
325 | static class Entry