ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
(Generate patch)

Comparing jsr166/src/jsr166e/ConcurrentHashMapV8.java (file contents):
Revision 1.4 by jsr166, Tue Aug 30 07:23:35 2011 UTC vs.
Revision 1.5 by dl, Tue Aug 30 11:35:39 2011 UTC

# Line 146 | Line 146 | public class ConcurrentHashMapV8<K, V>
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
# Line 515 | Line 519 | public class ConcurrentHashMapV8<K, V>
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) {
# Line 1119 | Line 1125 | public class ConcurrentHashMapV8<K, V>
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
# Line 1132 | Line 1143 | public class ConcurrentHashMapV8<K, V>
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       */
# Line 1142 | Line 1156 | public class ConcurrentHashMapV8<K, V>
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       *
# Line 1151 | Line 1165 | public class ConcurrentHashMapV8<K, V>
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
# Line 1167 | Line 1182 | public class ConcurrentHashMapV8<K, V>
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       */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines