146 |
|
* there is no existing node during a put operation, then one can |
147 |
|
* be CAS'ed in (without need for lock except in computeIfAbsent); |
148 |
|
* the CAS serves as validation. This is on average the most |
149 |
< |
* common case for put operations. The expected number of locks |
150 |
< |
* covering different elements (i.e., bins with 2 or more nodes) |
151 |
< |
* is approximately 10% at steady state under default settings. |
152 |
< |
* Lock contention probability for two threads accessing arbitrary |
153 |
< |
* distinct elements is thus less than 1% even for small tables. |
149 |
> |
* common case for put operations -- under random hash codes, the |
150 |
> |
* distribution of nodes in bins follows a Poisson distribution |
151 |
> |
* (see http://en.wikipedia.org/wiki/Poisson_distribution) with a |
152 |
> |
* parameter of 0.5 on average under the default loadFactor of |
153 |
> |
* 0.75. The expected number of locks covering different elements |
154 |
> |
* (i.e., bins with 2 or more nodes) is approximately 10% at |
155 |
> |
* steady state under default settings. Lock contention |
156 |
> |
* probability for two threads accessing arbitrary distinct |
157 |
> |
* elements is, roughly, 1 / (8 * #elements). |
158 |
|
* |
159 |
|
* The table is resized when occupancy exceeds a threshold. Only |
160 |
|
* a single thread performs the resize (using field "resizing", to |
519 |
|
} |
520 |
|
else if (e.hash < 0) |
521 |
|
tab = (Node[])e.key; |
522 |
+ |
else if (Thread.holdsLock(e)) |
523 |
+ |
throw new IllegalStateException("Recursive map computation"); |
524 |
|
else { |
525 |
|
boolean checkSize = false; |
526 |
|
synchronized (e) { |
1125 |
|
* </pre> |
1126 |
|
* |
1127 |
|
* except that the action is performed atomically. Some attempted |
1128 |
< |
* operations on this map by other threads may be blocked while |
1129 |
< |
* computation is in progress, so the computation should be short |
1130 |
< |
* and simple, and must not attempt to update any other mappings |
1131 |
< |
* of this Map. The most common usage is to construct a new object |
1132 |
< |
* serving as an initial mapped value, or memoized result. |
1128 |
> |
* update operations on this map by other threads may be blocked |
1129 |
> |
* while computation is in progress, so the computation should be |
1130 |
> |
* short and simple, and must not attempt to update any other |
1131 |
> |
* mappings of this Map. The most appropriate usage is to |
1132 |
> |
* construct a new object serving as an initial mapped value, or |
1133 |
> |
* memoized result, as in: |
1134 |
> |
* <pre>{@code |
1135 |
> |
* map.computeIfAbsent(key, new MappingFunction<K, V>() { |
1136 |
> |
* public V map(K k) { return new Value(f(k)); }}; |
1137 |
> |
* }</pre> |
1138 |
|
* |
1139 |
|
* @param key key with which the specified value is to be associated |
1140 |
|
* @param mappingFunction the function to compute a value |
1143 |
|
* returned {@code null}. |
1144 |
|
* @throws NullPointerException if the specified key or mappingFunction |
1145 |
|
* is null, |
1146 |
+ |
* @throws IllegalStateException if the computation detectably |
1147 |
+ |
* attempts a recursive update to this map that would |
1148 |
+ |
* otherwise never complete. |
1149 |
|
* @throws RuntimeException or Error if the mappingFunction does so, |
1150 |
|
* in which case the mapping is left unestablished. |
1151 |
|
*/ |
1156 |
|
} |
1157 |
|
|
1158 |
|
/** |
1159 |
< |
* Computes the value associated with he given key using the given |
1159 |
> |
* Computes the value associated with the given key using the given |
1160 |
|
* mappingFunction, and if non-null, enters it into the map. This |
1161 |
|
* is equivalent to |
1162 |
|
* |
1165 |
|
* if (value != null) |
1166 |
|
* map.put(key, value); |
1167 |
|
* else |
1168 |
< |
* return map.get(key); |
1168 |
> |
* value = map.get(key); |
1169 |
> |
* return value; |
1170 |
|
* </pre> |
1171 |
|
* |
1172 |
|
* except that the action is performed atomically. Some attempted |
1173 |
< |
* operations on this map by other threads may be blocked while |
1174 |
< |
* computation is in progress, so the computation should be short |
1175 |
< |
* and simple, and must not attempt to update any other mappings |
1176 |
< |
* of this Map. |
1173 |
> |
* update operations on this map by other threads may be blocked |
1174 |
> |
* while computation is in progress, so the computation should be |
1175 |
> |
* short and simple, and must not attempt to update any other |
1176 |
> |
* mappings of this Map. |
1177 |
|
* |
1178 |
|
* @param key key with which the specified value is to be associated |
1179 |
|
* @param mappingFunction the function to compute a value |
1182 |
|
* returned {@code null} and the value was not otherwise present. |
1183 |
|
* @throws NullPointerException if the specified key or mappingFunction |
1184 |
|
* is null, |
1185 |
+ |
* @throws IllegalStateException if the computation detectably |
1186 |
+ |
* attempts a recursive update to this map that would |
1187 |
+ |
* otherwise never complete. |
1188 |
|
* @throws RuntimeException or Error if the mappingFunction does so, |
1189 |
|
* in which case the mapping is unchanged. |
1190 |
|
*/ |