You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2009/07/28 11:30:48 UTC
svn commit: r798469 [15/28] - in /harmony/enhanced/classlib/branches/java6:
./ depends/build/platform/ depends/files/ depends/jars/
depends/manifests/icu4j_4.0/ depends/manifests/icu4j_4.2.1/
depends/manifests/icu4j_4.2.1/META-INF/ make/ modules/access...
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/TimeUnit.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/TimeUnit.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/TimeUnit.java Tue Jul 28 09:30:33 2009
@@ -12,7 +12,11 @@
* and to perform timing and delay operations in these units. A
* <tt>TimeUnit</tt> does not maintain time information, but only
* helps organize and use time representations that may be maintained
- * separately across various contexts.
+ * separately across various contexts. A nanosecond is defined as one
+ * thousandth of a microsecond, a microsecond as one thousandth of a
+ * millisecond, a millisecond as one thousandth of a second, a minute
+ * as sixty seconds, an hour as sixty minutes, and a day as twenty four
+ * hours.
*
* <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
* how a given timing parameter should be interpreted. For example,
@@ -36,62 +40,110 @@
* @author Doug Lea
*/
public enum TimeUnit {
- /** TimeUnit which represents one nanosecond. */
- NANOSECONDS(0),
- /** TimeUnit which represents one microsecond. */
- MICROSECONDS(1),
- /** TimeUnit which represents one millisecond. */
- MILLISECONDS(2),
- /** TimeUnit which represents one second. */
- SECONDS(3);
-
- /** the index of this unit */
- private final int index;
-
- /** Internal constructor */
- TimeUnit(int index) {
- this.index = index;
- }
-
- /** Lookup table for conversion factors */
- private static final int[] multipliers = {
- 1,
- 1000,
- 1000 * 1000,
- 1000 * 1000 * 1000
- };
-
- /**
- * Lookup table to check saturation. Note that because we are
- * dividing these down, we don't have to deal with asymmetry of
- * MIN/MAX values.
- */
- private static final long[] overflows = {
- 0, // unused
- Long.MAX_VALUE / 1000,
- Long.MAX_VALUE / (1000 * 1000),
- Long.MAX_VALUE / (1000 * 1000 * 1000)
+ NANOSECONDS {
+ public long toNanos(long d) { return d; }
+ public long toMicros(long d) { return d/(C1/C0); }
+ public long toMillis(long d) { return d/(C2/C0); }
+ public long toSeconds(long d) { return d/(C3/C0); }
+ public long toMinutes(long d) { return d/(C4/C0); }
+ public long toHours(long d) { return d/(C5/C0); }
+ public long toDays(long d) { return d/(C6/C0); }
+ public long convert(long d, TimeUnit u) { return u.toNanos(d); }
+ int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
+ },
+ MICROSECONDS {
+ public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
+ public long toMicros(long d) { return d; }
+ public long toMillis(long d) { return d/(C2/C1); }
+ public long toSeconds(long d) { return d/(C3/C1); }
+ public long toMinutes(long d) { return d/(C4/C1); }
+ public long toHours(long d) { return d/(C5/C1); }
+ public long toDays(long d) { return d/(C6/C1); }
+ public long convert(long d, TimeUnit u) { return u.toMicros(d); }
+ int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
+ },
+ MILLISECONDS {
+ public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
+ public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
+ public long toMillis(long d) { return d; }
+ public long toSeconds(long d) { return d/(C3/C2); }
+ public long toMinutes(long d) { return d/(C4/C2); }
+ public long toHours(long d) { return d/(C5/C2); }
+ public long toDays(long d) { return d/(C6/C2); }
+ public long convert(long d, TimeUnit u) { return u.toMillis(d); }
+ int excessNanos(long d, long m) { return 0; }
+ },
+ SECONDS {
+ public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
+ public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
+ public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
+ public long toSeconds(long d) { return d; }
+ public long toMinutes(long d) { return d/(C4/C3); }
+ public long toHours(long d) { return d/(C5/C3); }
+ public long toDays(long d) { return d/(C6/C3); }
+ public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
+ int excessNanos(long d, long m) { return 0; }
+ },
+ MINUTES {
+ public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
+ public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
+ public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
+ public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
+ public long toMinutes(long d) { return d; }
+ public long toHours(long d) { return d/(C5/C4); }
+ public long toDays(long d) { return d/(C6/C4); }
+ public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
+ int excessNanos(long d, long m) { return 0; }
+ },
+ HOURS {
+ public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
+ public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
+ public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
+ public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
+ public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
+ public long toHours(long d) { return d; }
+ public long toDays(long d) { return d/(C6/C5); }
+ public long convert(long d, TimeUnit u) { return u.toHours(d); }
+ int excessNanos(long d, long m) { return 0; }
+ },
+ DAYS {
+ public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
+ public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
+ public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
+ public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
+ public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
+ public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
+ public long toDays(long d) { return d; }
+ public long convert(long d, TimeUnit u) { return u.toDays(d); }
+ int excessNanos(long d, long m) { return 0; }
};
+ // Handy constants for conversion methods
+ static final long C0 = 1L;
+ static final long C1 = C0 * 1000L;
+ static final long C2 = C1 * 1000L;
+ static final long C3 = C2 * 1000L;
+ static final long C4 = C3 * 60L;
+ static final long C5 = C4 * 60L;
+ static final long C6 = C5 * 24L;
+
+ static final long MAX = Long.MAX_VALUE;
+
/**
- * Perform conversion based on given delta representing the
- * difference between units
- * @param delta the difference in index values of source and target units
- * @param duration the duration
- * @return converted duration or saturated value
- */
- private static long doConvert(int delta, long duration) {
- if (delta == 0)
- return duration;
- if (delta < 0)
- return duration / multipliers[-delta];
- if (duration > overflows[delta])
- return Long.MAX_VALUE;
- if (duration < -overflows[delta])
- return Long.MIN_VALUE;
- return duration * multipliers[delta];
+ * Scale d by m, checking for overflow.
+ * This has a short name to make above code more readable.
+ */
+ static long x(long d, long m, long over) {
+ if (d > over) return Long.MAX_VALUE;
+ if (d < -over) return Long.MIN_VALUE;
+ return d * m;
}
+ // To maintain full signature compatibility with 1.5, and to improve the
+ // clarity of the generated javadoc (see 6287639: Abstract methods in
+ // enum classes should not be listed as abstract), method convert
+ // etc. are not declared abstract but otherwise act as abstract methods.
+
/**
* Convert the given time duration in the given unit to this
* unit. Conversions from finer to coarser granularities
@@ -102,14 +154,17 @@
* <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
* if positive.
*
- * @param duration the time duration in the given <tt>unit</tt>
- * @param unit the unit of the <tt>duration</tt> argument
+ * <p>For example, to convert 10 minutes to milliseconds, use:
+ * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
+ *
+ * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
+ * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
* @return the converted duration in this unit,
* or <tt>Long.MIN_VALUE</tt> if conversion would negatively
* overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
*/
- public long convert(long duration, TimeUnit unit) {
- return doConvert(unit.index - index, duration);
+ public long convert(long sourceDuration, TimeUnit sourceUnit) {
+ throw new AbstractMethodError();
}
/**
@@ -121,7 +176,7 @@
* @see #convert
*/
public long toNanos(long duration) {
- return doConvert(index, duration);
+ throw new AbstractMethodError();
}
/**
@@ -133,7 +188,7 @@
* @see #convert
*/
public long toMicros(long duration) {
- return doConvert(index - MICROSECONDS.index, duration);
+ throw new AbstractMethodError();
}
/**
@@ -145,34 +200,66 @@
* @see #convert
*/
public long toMillis(long duration) {
- return doConvert(index - MILLISECONDS.index, duration);
+ throw new AbstractMethodError();
}
/**
* Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
* @param duration the duration
- * @return the converted duration.
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
* @see #convert
*/
public long toSeconds(long duration) {
- return doConvert(index - SECONDS.index, duration);
+ throw new AbstractMethodError();
}
+ /**
+ * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ * @see #convert
+ */
+ long toMinutes(long duration) {
+ throw new AbstractMethodError();
+ }
/**
- * Utility method to compute the excess-nanosecond argument to
- * wait, sleep, join.
+ * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ * @see #convert
*/
- private int excessNanos(long time, long ms) {
- if (this == NANOSECONDS)
- return (int) (time - (ms * 1000 * 1000));
- if (this == MICROSECONDS)
- return (int) ((time * 1000) - (ms * 1000 * 1000));
- return 0;
+ long toHours(long duration) {
+ throw new AbstractMethodError();
}
/**
- * Perform a timed <tt>Object.wait</tt> using this time unit.
+ * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration
+ * @see #convert
+ */
+ long toDays(long duration) {
+ throw new AbstractMethodError();
+ }
+
+ /**
+ * Utility to compute the excess-nanosecond argument to wait,
+ * sleep, join.
+ * @param d the duration
+ * @param m the number of milliseconds
+ * @return the number of nanoseconds
+ */
+ abstract int excessNanos(long d, long m);
+
+ /**
+ * Performs a timed <tt>Object.wait</tt> using this time unit.
* This is a convenience method that converts timeout arguments
* into the form required by the <tt>Object.wait</tt> method.
*
@@ -180,7 +267,7 @@
* method (see {@link BlockingQueue#poll BlockingQueue.poll})
* using:
*
- * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
+ * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
* while (empty) {
* unit.timedWait(this, timeout);
* ...
@@ -188,12 +275,13 @@
* }</pre>
*
* @param obj the object to wait on
- * @param timeout the maximum time to wait.
+ * @param timeout the maximum time to wait. If less than
+ * or equal to zero, do not wait at all.
* @throws InterruptedException if interrupted while waiting.
* @see Object#wait(long, int)
*/
public void timedWait(Object obj, long timeout)
- throws InterruptedException {
+ throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
@@ -202,16 +290,17 @@
}
/**
- * Perform a timed <tt>Thread.join</tt> using this time unit.
+ * Performs a timed <tt>Thread.join</tt> using this time unit.
* This is a convenience method that converts time arguments into the
* form required by the <tt>Thread.join</tt> method.
* @param thread the thread to wait for
- * @param timeout the maximum time to wait
+ * @param timeout the maximum time to wait. If less than
+ * or equal to zero, do not wait at all.
* @throws InterruptedException if interrupted while waiting.
* @see Thread#join(long, int)
*/
public void timedJoin(Thread thread, long timeout)
- throws InterruptedException {
+ throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
@@ -220,10 +309,11 @@
}
/**
- * Perform a <tt>Thread.sleep</tt> using this unit.
+ * Performs a <tt>Thread.sleep</tt> using this unit.
* This is a convenience method that converts time arguments into the
* form required by the <tt>Thread.sleep</tt> method.
- * @param timeout the minimum time to sleep
+ * @param timeout the minimum time to sleep. If less than
+ * or equal to zero, do not sleep at all.
* @throws InterruptedException if interrupted while sleeping.
* @see Thread#sleep
*/
Propchange: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jul 28 09:30:33 2009
@@ -1 +1 @@
-/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic:765923-790471
+/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic:765923-798021
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java Tue Jul 28 09:30:33 2009
@@ -8,10 +8,10 @@
import sun.misc.Unsafe;
/**
- * A <tt>boolean</tt> value that may be updated atomically. See the
+ * A {@code boolean} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for
* description of the properties of atomic variables. An
- * <tt>AtomicBoolean</tt> is used in applications such as atomically
+ * {@code AtomicBoolean} is used in applications such as atomically
* updated flags, and cannot be used as a replacement for a
* {@link java.lang.Boolean}.
*
@@ -21,7 +21,7 @@
public class AtomicBoolean implements java.io.Serializable {
private static final long serialVersionUID = 4654671469794556979L;
// setup to use Unsafe.compareAndSwapInt for updates
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
@@ -34,7 +34,7 @@
private volatile int value;
/**
- * Creates a new <tt>AtomicBoolean</tt> with the given initial value.
+ * Creates a new {@code AtomicBoolean} with the given initial value.
*
* @param initialValue the initial value
*/
@@ -43,7 +43,7 @@
}
/**
- * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>.
+ * Creates a new {@code AtomicBoolean} with initial value {@code false}.
*/
public AtomicBoolean() {
}
@@ -58,16 +58,13 @@
}
/**
- * Atomically sets the value to the given update value if the
- * current value is equal to the expected value. Any given
- * invocation of this operation may fail (return
- * <tt>false</tt>) spuriously, but repeated invocation when
- * the current value holds the expected value and no other thread
- * is also attempting to set the value will eventually succeed.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
- * @return true if successful
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
@@ -76,9 +73,13 @@
}
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
- * May fail spuriously.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param expect the expected value
* @param update the new value
* @return true if successful.
@@ -99,7 +100,7 @@
}
/**
- * Sets to the given value and returns the previous value.
+ * Atomically sets to the given value and returns the previous value.
*
* @param newValue the new value
* @return the previous value
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java Tue Jul 28 09:30:33 2009
@@ -8,37 +8,36 @@
import sun.misc.Unsafe;
/**
- * An <tt>int</tt> value that may be updated atomically. See the
+ * An {@code int} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for
* description of the properties of atomic variables. An
- * <tt>AtomicInteger</tt> is used in applications such as atomically
+ * {@code AtomicInteger} is used in applications such as atomically
* incremented counters, and cannot be used as a replacement for an
* {@link java.lang.Integer}. However, this class does extend
- * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * {@code Number} to allow uniform access by tools and utilities that
* deal with numerically-based classes.
- *
*
* @since 1.5
* @author Doug Lea
*/
-public class AtomicInteger extends Number implements java.io.Serializable {
+public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
- } catch(Exception ex) { throw new Error(ex); }
+ } catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
/**
- * Create a new AtomicInteger with the given initial value.
+ * Creates a new AtomicInteger with the given initial value.
*
* @param initialValue the initial value
*/
@@ -47,22 +46,22 @@
}
/**
- * Create a new AtomicInteger with initial value <tt>0</tt>.
+ * Creates a new AtomicInteger with initial value {@code 0}.
*/
public AtomicInteger() {
}
/**
- * Get the current value.
+ * Gets the current value.
*
* @return the current value
*/
public final int get() {
return value;
}
-
+
/**
- * Set to the given value.
+ * Sets to the given value.
*
* @param newValue the new value
*/
@@ -71,7 +70,7 @@
}
/**
- * Set to the give value and return the old value.
+ * Atomically sets to the given value and returns the old value.
*
* @param newValue the new value
* @return the previous value
@@ -83,35 +82,39 @@
return current;
}
}
-
-
+
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
* @param expect the expected value
* @param update the new value
* @return true if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
- return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
- * May fail spuriously.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param expect the expected value
* @param update the new value
* @return true if successful.
*/
public final boolean weakCompareAndSet(int expect, int update) {
- return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
-
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value.
+ *
* @return the previous value
*/
public final int getAndIncrement() {
@@ -122,10 +125,10 @@
return current;
}
}
-
-
+
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value.
+ *
* @return the previous value
*/
public final int getAndDecrement() {
@@ -136,10 +139,10 @@
return current;
}
}
-
-
+
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value.
+ *
* @param delta the value to add
* @return the previous value
*/
@@ -153,7 +156,8 @@
}
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value.
+ *
* @return the updated value
*/
public final int incrementAndGet() {
@@ -164,9 +168,10 @@
return next;
}
}
-
+
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value.
+ *
* @return the updated value
*/
public final int decrementAndGet() {
@@ -177,10 +182,10 @@
return next;
}
}
-
-
+
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value.
+ *
* @param delta the value to add
* @return the updated value
*/
@@ -203,19 +208,19 @@
public int intValue() {
- return get();
+ return get();
}
public long longValue() {
- return (long)get();
+ return (long)get();
}
public float floatValue() {
- return (float)get();
+ return (float)get();
}
public double doubleValue() {
- return (double)get();
+ return (double)get();
}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java Tue Jul 28 09:30:33 2009
@@ -9,18 +9,18 @@
import java.util.*;
/**
- * An <tt>int</tt> array in which elements may be updated atomically.
+ * An {@code int} array in which elements may be updated atomically.
* See the {@link java.util.concurrent.atomic} package
* specification for description of the properties of atomic
* variables.
* @since 1.5
* @author Doug Lea
*/
-public class AtomicIntegerArray implements java.io.Serializable {
+public class AtomicIntegerArray implements java.io.Serializable {
private static final long serialVersionUID = 2862133569453604235L;
// setup to use Unsafe.compareAndSwapInt for updates
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int base = unsafe.arrayBaseOffset(int[].class);
private static final int scale = unsafe.arrayIndexScale(int[].class);
private final int[] array;
@@ -32,7 +32,7 @@
}
/**
- * Create a new AtomicIntegerArray of given length.
+ * Creates a new AtomicIntegerArray of given length.
*
* @param length the length of the array
*/
@@ -44,14 +44,14 @@
}
/**
- * Create a new AtomicIntegerArray with the same length as, and
+ * Creates a new AtomicIntegerArray with the same length as, and
* all elements copied from, the given array.
*
* @param array the array to copy elements from
* @throws NullPointerException if array is null
*/
public AtomicIntegerArray(int[] array) {
- if (array == null)
+ if (array == null)
throw new NullPointerException();
int length = array.length;
this.array = new int[length];
@@ -74,7 +74,7 @@
}
/**
- * Get the current value at position <tt>i</tt>.
+ * Gets the current value at position {@code i}.
*
* @param i the index
* @return the current value
@@ -82,9 +82,9 @@
public final int get(int i) {
return unsafe.getIntVolatile(array, rawIndex(i));
}
-
+
/**
- * Set the element at position <tt>i</tt> to the given value.
+ * Sets the element at position {@code i} to the given value.
*
* @param i the index
* @param newValue the new value
@@ -92,10 +92,10 @@
public final void set(int i, int newValue) {
unsafe.putIntVolatile(array, rawIndex(i), newValue);
}
-
+
/**
- * Set the element at position <tt>i</tt> to the given value and return the
- * old value.
+ * Atomically sets the element at position {@code i} to the given
+ * value and returns the old value.
*
* @param i the index
* @param newValue the new value
@@ -108,10 +108,10 @@
return current;
}
}
-
+
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
+ * Atomically sets the element at position {@code i} to the given
+ * updated value if the current value {@code ==} the expected value.
*
* @param i the index
* @param expect the expected value
@@ -120,14 +120,17 @@
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int i, int expect, int update) {
- return unsafe.compareAndSwapInt(array, rawIndex(i),
+ return unsafe.compareAndSwapInt(array, rawIndex(i),
expect, update);
}
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
- * May fail spuriously.
+ * Atomically sets the element at position {@code i} to the given
+ * updated value if the current value {@code ==} the expected value.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
*
* @param i the index
* @param expect the expected value
@@ -139,10 +142,10 @@
}
/**
- * Atomically increment by one the element at index <tt>i</tt>.
+ * Atomically increments by one the element at index {@code i}.
*
* @param i the index
- * @return the previous value;
+ * @return the previous value
*/
public final int getAndIncrement(int i) {
while (true) {
@@ -152,12 +155,12 @@
return current;
}
}
-
+
/**
- * Atomically decrement by one the element at index <tt>i</tt>.
+ * Atomically decrements by one the element at index {@code i}.
*
* @param i the index
- * @return the previous value;
+ * @return the previous value
*/
public final int getAndDecrement(int i) {
while (true) {
@@ -167,13 +170,13 @@
return current;
}
}
-
+
/**
- * Atomically add the given value to element at index <tt>i</tt>.
+ * Atomically adds the given value to the element at index {@code i}.
*
* @param i the index
* @param delta the value to add
- * @return the previous value;
+ * @return the previous value
*/
public final int getAndAdd(int i, int delta) {
while (true) {
@@ -185,10 +188,10 @@
}
/**
- * Atomically increment by one the element at index <tt>i</tt>.
+ * Atomically increments by one the element at index {@code i}.
*
* @param i the index
- * @return the updated value;
+ * @return the updated value
*/
public final int incrementAndGet(int i) {
while (true) {
@@ -198,12 +201,12 @@
return next;
}
}
-
+
/**
- * Atomically decrement by one the element at index <tt>i</tt>.
+ * Atomically decrements by one the element at index {@code i}.
*
* @param i the index
- * @return the updated value;
+ * @return the updated value
*/
public final int decrementAndGet(int i) {
while (true) {
@@ -213,13 +216,13 @@
return next;
}
}
-
+
/**
- * Atomically add the given value to element at index <tt>i</tt>.
+ * Atomically adds the given value to the element at index {@code i}.
*
* @param i the index
* @param delta the value to add
- * @return the updated value;
+ * @return the updated value
*/
public final int addAndGet(int i, int delta) {
while (true) {
@@ -229,7 +232,7 @@
return next;
}
}
-
+
/**
* Returns the String representation of the current values of array.
* @return the String representation of the current values of array.
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Jul 28 09:30:33 2009
@@ -8,35 +8,39 @@
import sun.misc.Unsafe;
import java.lang.reflect.*;
+import org.apache.harmony.kernel.vm.VM;
+
/**
* A reflection-based utility that enables atomic updates to
- * designated <tt>volatile int</tt> fields of designated classes.
+ * designated {@code volatile int} fields of designated classes.
* This class is designed for use in atomic data structures in which
* several fields of the same node are independently subject to atomic
* updates.
*
- * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
- * in this class are weaker than in other atomic classes. Because this
- * class cannot ensure that all uses of the field are appropriate for
- * purposes of atomic access, it can guarantee atomicity and volatile
- * semantics only with respect to other invocations of
- * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
* @since 1.5
* @author Doug Lea
* @param <T> The type of the object holding the updatable field
*/
public abstract class AtomicIntegerFieldUpdater<T> {
/**
- * Creates an updater for objects with the given field. The Class
- * argument is needed to check that reflective types and generic
- * types match.
+ * Creates and returns an updater for objects with the given field.
+ * The Class argument is needed to check that reflective types and
+ * generic types match.
+ *
* @param tclass the class of the objects holding the field
- * @param fieldName the name of the field to be updated.
+ * @param fieldName the name of the field to be updated
* @return the updater
* @throws IllegalArgumentException if the field is not a
- * volatile integer type.
+ * volatile integer type
* @throws RuntimeException with a nested reflection-based
- * exception if the class does not hold field or is the wrong type.
+ * exception if the class does not hold field or is the wrong type
*/
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
@@ -49,57 +53,63 @@
}
/**
- * Atomically set the value of the field of the given object managed
- * by this Updater to the given updated value if the current value
- * <tt>==</tt> the expected value. This method is guaranteed to be
- * atomic with respect to other calls to <tt>compareAndSet</tt> and
- * <tt>set</tt>, but not necessarily with respect to other
- * changes in the field.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value {@code ==} the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to {@code compareAndSet} and {@code set}, but not
+ * necessarily with respect to other changes in the field.
+ *
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
- * @return true if successful.
- * @throws ClassCastException if <tt>obj</tt> is not an instance
- * of the class possessing the field established in the constructor.
+ * @return true if successful
+ * @throws ClassCastException if {@code obj} is not an instance
+ * of the class possessing the field established in the constructor
*/
-
public abstract boolean compareAndSet(T obj, int expect, int update);
/**
- * Atomically set the value of the field of the given object managed
- * by this Updater to the given updated value if the current value
- * <tt>==</tt> the expected value. This method is guaranteed to be
- * atomic with respect to other calls to <tt>compareAndSet</tt> and
- * <tt>set</tt>, but not necessarily with respect to other
- * changes in the field, and may fail spuriously.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value {@code ==} the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to {@code compareAndSet} and {@code set}, but not
+ * necessarily with respect to other changes in the field.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
- * @return true if successful.
- * @throws ClassCastException if <tt>obj</tt> is not an instance
- * of the class possessing the field established in the constructor.
+ * @return true if successful
+ * @throws ClassCastException if {@code obj} is not an instance
+ * of the class possessing the field established in the constructor
*/
-
public abstract boolean weakCompareAndSet(T obj, int expect, int update);
/**
- * Set the field of the given object managed by this updater. This
- * operation is guaranteed to act as a volatile store with respect
- * to subsequent invocations of <tt>compareAndSet</tt>.
+ * Sets the field of the given object managed by this updater to the
+ * given updated value. This operation is guaranteed to act as a volatile
+ * store with respect to subsequent invocations of {@code compareAndSet}.
+ *
* @param obj An object whose field to set
* @param newValue the new value
*/
public abstract void set(T obj, int newValue);
/**
- * Get the current value held in the field by the given object.
+ * Gets the current value held in the field of the given object managed
+ * by this updater.
+ *
* @param obj An object whose field to get
* @return the current value
*/
public abstract int get(T obj);
/**
- * Set to the given value and return the old value.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given value and returns the old value.
*
* @param obj An object whose field to get and set
* @param newValue the new value
@@ -114,9 +124,11 @@
}
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the previous value;
+ * @return the previous value
*/
public int getAndIncrement(T obj) {
for (;;) {
@@ -127,11 +139,12 @@
}
}
-
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the previous value;
+ * @return the previous value
*/
public int getAndDecrement(T obj) {
for (;;) {
@@ -142,12 +155,13 @@
}
}
-
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
* @param obj An object whose field to get and set
* @param delta the value to add
- * @return the previous value;
+ * @return the previous value
*/
public int getAndAdd(T obj, int delta) {
for (;;) {
@@ -159,9 +173,11 @@
}
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the updated value;
+ * @return the updated value
*/
public int incrementAndGet(T obj) {
for (;;) {
@@ -172,11 +188,12 @@
}
}
-
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the updated value;
+ * @return the updated value
*/
public int decrementAndGet(T obj) {
for (;;) {
@@ -187,12 +204,13 @@
}
}
-
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
* @param obj An object whose field to get and set
* @param delta the value to add
- * @return the updated value;
+ * @return the updated value
*/
public int addAndGet(T obj, int delta) {
for (;;) {
@@ -207,52 +225,84 @@
* Standard hotspot implementation using intrinsics
*/
private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
+ private final Class cclass;
AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
Field field = null;
+ Class caller = null;
+ int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- } catch(Exception ex) {
+ caller = VM.getStackClass(2);
+ modifiers = field.getModifiers();
+
+ SecurityManager smgr = System.getSecurityManager();
+ if (smgr != null) {
+ int type = Modifier.isPublic(modifiers)
+ ? Member.PUBLIC : Member.DECLARED;
+ smgr.checkMemberAccess(tclass, type);
+ smgr.checkPackageAccess(tclass.getPackage().getName());
+ }
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
-
+
Class fieldt = field.getType();
if (fieldt != int.class)
throw new IllegalArgumentException("Must be integer type");
-
- if (!Modifier.isVolatile(field.getModifiers()))
+
+ if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
-
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
this.tclass = tclass;
offset = unsafe.objectFieldOffset(field);
}
- public boolean compareAndSet(T obj, int expect, int update) {
+ private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, int expect, int update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, int expect, int update) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
public void set(T obj, int newValue) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
unsafe.putIntVolatile(obj, offset, newValue);
}
public final int get(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getIntVolatile(obj, offset);
}
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException(
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
}
}
-
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java Tue Jul 28 09:30:33 2009
@@ -8,32 +8,34 @@
import sun.misc.Unsafe;
/**
- * A <tt>long</tt> value that may be updated atomically. See the
+ * A {@code long} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for
* description of the properties of atomic variables. An
- * <tt>AtomicLong</tt> is used in applications such as atomically
+ * {@code AtomicLong} is used in applications such as atomically
* incremented sequence numbers, and cannot be used as a replacement
* for a {@link java.lang.Long}. However, this class does extend
- * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * {@code Number} to allow uniform access by tools and utilities that
* deal with numerically-based classes.
*
* @since 1.5
* @author Doug Lea
*/
-public class AtomicLong extends Number implements java.io.Serializable {
+public class AtomicLong extends Number implements java.io.Serializable {
private static final long serialVersionUID = 1927816293512124184L;
// setup to use Unsafe.compareAndSwapLong for updates
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
/**
- * Record whether the underlying JVM supports lockless
- * CompareAndSet for longs. While the unsafe.CompareAndSetLong
+ * Records whether the underlying JVM supports lockless
+ * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
* method works in either case, some constructions should be
* handled at Java level to avoid locking user-visible locks.
+ *
+ * Initialised in the static block.
*/
- static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
+ static final boolean VM_SUPPORTS_LONG_CAS;
/**
* Returns whether underlying JVM supports lockless CompareAndSet
@@ -45,13 +47,22 @@
try {
valueOffset = unsafe.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
- } catch(Exception ex) { throw new Error(ex); }
+ } catch (Exception ex) { throw new Error(ex); }
+
+ boolean longCASSupport;
+ try {
+ longCASSupport = VMSupportsCS8();
+ } catch (UnsatisfiedLinkError e) {
+ // assume there's support if the native isn't provided by the VM
+ longCASSupport = true;
+ }
+ VM_SUPPORTS_LONG_CAS = longCASSupport;
}
private volatile long value;
/**
- * Create a new AtomicLong with the given initial value.
+ * Creates a new AtomicLong with the given initial value.
*
* @param initialValue the initial value
*/
@@ -60,31 +71,31 @@
}
/**
- * Create a new AtomicLong with initial value <tt>0</tt>.
+ * Creates a new AtomicLong with initial value {@code 0}.
*/
public AtomicLong() {
}
-
+
/**
- * Get the current value.
+ * Gets the current value.
*
* @return the current value
*/
public final long get() {
return value;
}
-
+
/**
- * Set to the given value.
+ * Sets to the given value.
*
* @param newValue the new value
*/
public final void set(long newValue) {
value = newValue;
}
-
+
/**
- * Set to the give value and return the old value.
+ * Atomically sets to the given value and returns the old value.
*
* @param newValue the new value
* @return the previous value
@@ -96,33 +107,39 @@
return current;
}
}
-
+
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
* @param expect the expected value
* @param update the new value
* @return true if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(long expect, long update) {
- return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
- * May fail spuriously.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param expect the expected value
* @param update the new value
* @return true if successful.
*/
public final boolean weakCompareAndSet(long expect, long update) {
- return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
-
+
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value.
+ *
* @return the previous value
*/
public final long getAndIncrement() {
@@ -133,10 +150,10 @@
return current;
}
}
-
-
+
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value.
+ *
* @return the previous value
*/
public final long getAndDecrement() {
@@ -147,10 +164,10 @@
return current;
}
}
-
-
+
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value.
+ *
* @param delta the value to add
* @return the previous value
*/
@@ -162,9 +179,10 @@
return current;
}
}
-
+
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value.
+ *
* @return the updated value
*/
public final long incrementAndGet() {
@@ -175,9 +193,10 @@
return next;
}
}
-
+
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value.
+ *
* @return the updated value
*/
public final long decrementAndGet() {
@@ -188,10 +207,10 @@
return next;
}
}
-
-
+
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value.
+ *
* @param delta the value to add
* @return the updated value
*/
@@ -203,7 +222,7 @@
return next;
}
}
-
+
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
@@ -214,19 +233,19 @@
public int intValue() {
- return (int)get();
+ return (int)get();
}
public long longValue() {
- return (long)get();
+ return get();
}
public float floatValue() {
- return (float)get();
+ return (float)get();
}
public double doubleValue() {
- return (double)get();
+ return (double)get();
}
-
+
}
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java Tue Jul 28 09:30:33 2009
@@ -9,17 +9,17 @@
import java.util.*;
/**
- * A <tt>long</tt> array in which elements may be updated atomically.
+ * A {@code long} array in which elements may be updated atomically.
* See the {@link java.util.concurrent.atomic} package specification
* for description of the properties of atomic variables.
* @since 1.5
* @author Doug Lea
*/
-public class AtomicLongArray implements java.io.Serializable {
+public class AtomicLongArray implements java.io.Serializable {
private static final long serialVersionUID = -2308431214976778248L;
// setup to use Unsafe.compareAndSwapInt for updates
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int base = unsafe.arrayBaseOffset(long[].class);
private static final int scale = unsafe.arrayIndexScale(long[].class);
private final long[] array;
@@ -31,25 +31,26 @@
}
/**
- * Create a new AtomicLongArray of given length.
+ * Creates a new AtomicLongArray of given length.
+ *
* @param length the length of the array
*/
public AtomicLongArray(int length) {
array = new long[length];
// must perform at least one volatile write to conform to JMM
- if (length > 0)
+ if (length > 0)
unsafe.putLongVolatile(array, rawIndex(0), 0);
}
/**
- * Create a new AtomicLongArray with the same length as, and
+ * Creates a new AtomicLongArray with the same length as, and
* all elements copied from, the given array.
*
* @param array the array to copy elements from
* @throws NullPointerException if array is null
*/
public AtomicLongArray(long[] array) {
- if (array == null)
+ if (array == null)
throw new NullPointerException();
int length = array.length;
this.array = new long[length];
@@ -72,7 +73,7 @@
}
/**
- * Get the current value at position <tt>i</tt>.
+ * Gets the current value at position {@code i}.
*
* @param i the index
* @return the current value
@@ -80,9 +81,9 @@
public final long get(int i) {
return unsafe.getLongVolatile(array, rawIndex(i));
}
-
+
/**
- * Set the element at position <tt>i</tt> to the given value.
+ * Sets the element at position {@code i} to the given value.
*
* @param i the index
* @param newValue the new value
@@ -90,10 +91,10 @@
public final void set(int i, long newValue) {
unsafe.putLongVolatile(array, rawIndex(i), newValue);
}
-
+
/**
- * Set the element at position <tt>i</tt> to the given value and return the
- * old value.
+ * Atomically sets the element at position {@code i} to the given value
+ * and returns the old value.
*
* @param i the index
* @param newValue the new value
@@ -106,10 +107,11 @@
return current;
}
}
-
+
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
* @param i the index
* @param expect the expected value
* @param update the new value
@@ -117,14 +119,18 @@
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int i, long expect, long update) {
- return unsafe.compareAndSwapLong(array, rawIndex(i),
+ return unsafe.compareAndSwapLong(array, rawIndex(i),
expect, update);
}
/**
- * Atomically set the value to the given updated value
- * if the current value <tt>==</tt> the expected value.
- * May fail spuriously.
+ * Atomically sets the value to the given updated value
+ * if the current value {@code ==} the expected value.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param i the index
* @param expect the expected value
* @param update the new value
@@ -135,10 +141,10 @@
}
/**
- * Atomically increment by one the element at index <tt>i</tt>.
+ * Atomically increments by one the element at index {@code i}.
*
* @param i the index
- * @return the previous value;
+ * @return the previous value
*/
public final long getAndIncrement(int i) {
while (true) {
@@ -148,12 +154,12 @@
return current;
}
}
-
+
/**
- * Atomically decrement by one the element at index <tt>i</tt>.
+ * Atomically decrements by one the element at index {@code i}.
*
* @param i the index
- * @return the previous value;
+ * @return the previous value
*/
public final long getAndDecrement(int i) {
while (true) {
@@ -163,13 +169,13 @@
return current;
}
}
-
+
/**
- * Atomically add the given value to element at index <tt>i</tt>.
+ * Atomically adds the given value to the element at index {@code i}.
*
* @param i the index
* @param delta the value to add
- * @return the previous value;
+ * @return the previous value
*/
public final long getAndAdd(int i, long delta) {
while (true) {
@@ -179,13 +185,12 @@
return current;
}
}
-
/**
- * Atomically increment the element at index <tt>i</tt>.
+ * Atomically increments by one the element at index {@code i}.
*
* @param i the index
- * @return the updated value;
+ * @return the updated value
*/
public final long incrementAndGet(int i) {
while (true) {
@@ -195,12 +200,12 @@
return next;
}
}
-
+
/**
- * Atomically decrement the element at index <tt>i</tt>.
+ * Atomically decrements by one the element at index {@code i}.
*
* @param i the index
- * @return the updated value;
+ * @return the updated value
*/
public final long decrementAndGet(int i) {
while (true) {
@@ -210,13 +215,13 @@
return next;
}
}
-
+
/**
- * Atomically add the given value to element at index <tt>i</tt>.
+ * Atomically adds the given value to the element at index {@code i}.
*
* @param i the index
* @param delta the value to add
- * @return the updated value;
+ * @return the updated value
*/
public long addAndGet(int i, long delta) {
while (true) {
@@ -236,5 +241,5 @@
get(0);
return Arrays.toString(array);
}
-
+
}
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Jul 28 09:30:33 2009
@@ -8,19 +8,21 @@
import sun.misc.Unsafe;
import java.lang.reflect.*;
+import org.apache.harmony.kernel.vm.VM;
+
/**
* A reflection-based utility that enables atomic updates to
- * designated <tt>volatile long</tt> fields of designated classes.
+ * designated {@code volatile long} fields of designated classes.
* This class is designed for use in atomic data structures in which
* several fields of the same node are independently subject to atomic
* updates.
*
- * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
- * in this class are weaker than in other atomic classes. Because this
- * class cannot ensure that all uses of the field are appropriate for
- * purposes of atomic access, it can guarantee atomicity and volatile
- * semantics only with respect to other invocations of
- * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
*
* @since 1.5
* @author Doug Lea
@@ -28,9 +30,10 @@
*/
public abstract class AtomicLongFieldUpdater<T> {
/**
- * Creates an updater for objects with the given field. The Class
- * argument is needed to check that reflective types and generic
- * types match.
+ * Creates and returns an updater for objects with the given field.
+ * The Class argument is needed to check that reflective types and
+ * generic types match.
+ *
* @param tclass the class of the objects holding the field
* @param fieldName the name of the field to be updated.
* @return the updater
@@ -53,57 +56,63 @@
}
/**
- * Atomically set the value of the field of the given object managed
- * by this Updater to the given updated value if the current value
- * <tt>==</tt> the expected value. This method is guaranteed to be
- * atomic with respect to other calls to <tt>compareAndSet</tt> and
- * <tt>set</tt>, but not necessarily with respect to other
- * changes in the field.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value {@code ==} the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to {@code compareAndSet} and {@code set}, but not
+ * necessarily with respect to other changes in the field.
+ *
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
- * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor.
*/
-
public abstract boolean compareAndSet(T obj, long expect, long update);
/**
- * Atomically set the value of the field of the given object managed
- * by this Updater to the given updated value if the current value
- * <tt>==</tt> the expected value. This method is guaranteed to be
- * atomic with respect to other calls to <tt>compareAndSet</tt> and
- * <tt>set</tt>, but not necessarily with respect to other
- * changes in the field, and may fail spuriously.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value {@code ==} the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to {@code compareAndSet} and {@code set}, but not
+ * necessarily with respect to other changes in the field.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
+ *
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
- * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor.
*/
-
public abstract boolean weakCompareAndSet(T obj, long expect, long update);
/**
- * Set the field of the given object managed by this updater. This
- * operation is guaranteed to act as a volatile store with respect
- * to subsequent invocations of <tt>compareAndSet</tt>.
+ * Sets the field of the given object managed by this updater to the
+ * given updated value. This operation is guaranteed to act as a volatile
+ * store with respect to subsequent invocations of {@code compareAndSet}.
+ *
* @param obj An object whose field to set
* @param newValue the new value
*/
public abstract void set(T obj, long newValue);
/**
- * Get the current value held in the field by the given object.
+ * Gets the current value held in the field of the given object managed
+ * by this updater.
+ *
* @param obj An object whose field to get
* @return the current value
*/
public abstract long get(T obj);
/**
- * Set to the given value and return the old value.
+ * Atomically sets the field of the given object managed by this updater
+ * to the given value and returns the old value.
*
* @param obj An object whose field to get and set
* @param newValue the new value
@@ -118,9 +127,11 @@
}
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the previous value;
+ * @return the previous value
*/
public long getAndIncrement(T obj) {
for (;;) {
@@ -131,11 +142,12 @@
}
}
-
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the previous value;
+ * @return the previous value
*/
public long getAndDecrement(T obj) {
for (;;) {
@@ -146,12 +158,13 @@
}
}
-
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
* @param obj An object whose field to get and set
* @param delta the value to add
- * @return the previous value;
+ * @return the previous value
*/
public long getAndAdd(T obj, long delta) {
for (;;) {
@@ -163,9 +176,11 @@
}
/**
- * Atomically increment by one the current value.
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the updated value;
+ * @return the updated value
*/
public long incrementAndGet(T obj) {
for (;;) {
@@ -176,11 +191,12 @@
}
}
-
/**
- * Atomically decrement by one the current value.
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
* @param obj An object whose field to get and set
- * @return the updated value;
+ * @return the updated value
*/
public long decrementAndGet(T obj) {
for (;;) {
@@ -191,12 +207,13 @@
}
}
-
/**
- * Atomically add the given value to current value.
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
* @param obj An object whose field to get and set
* @param delta the value to add
- * @return the updated value;
+ * @return the updated value
*/
public long addAndGet(T obj, long delta) {
for (;;) {
@@ -208,85 +225,137 @@
}
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
+ private final Class cclass;
CASUpdater(Class<T> tclass, String fieldName) {
Field field = null;
+ Class caller = null;
+ int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- } catch(Exception ex) {
+ caller = VM.getStackClass(2);
+ modifiers = field.getModifiers();
+ SecurityManager smgr = System.getSecurityManager();
+ if (smgr != null) {
+ int type = Modifier.isPublic(modifiers)
+ ? Member.PUBLIC : Member.DECLARED;
+ smgr.checkMemberAccess(tclass, type);
+ smgr.checkPackageAccess(tclass.getPackage().getName());
+ }
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
-
+
Class fieldt = field.getType();
if (fieldt != long.class)
throw new IllegalArgumentException("Must be long type");
-
- if (!Modifier.isVolatile(field.getModifiers()))
+
+ if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
-
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
this.tclass = tclass;
offset = unsafe.objectFieldOffset(field);
}
- public boolean compareAndSet(T obj, long expect, long update) {
+ private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, long expect, long update) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
public void set(T obj, long newValue) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
unsafe.putLongVolatile(obj, offset, newValue);
}
public long get(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getLongVolatile(obj, offset);
}
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException (
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
}
private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
+ private final Class cclass;
LockedUpdater(Class<T> tclass, String fieldName) {
Field field = null;
+ Class caller = null;
+ int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
- } catch(Exception ex) {
+ caller = VM.getStackClass(2);
+ modifiers = field.getModifiers();
+ SecurityManager smgr = System.getSecurityManager();
+ if (smgr != null) {
+ int type = Modifier.isPublic(modifiers)
+ ? Member.PUBLIC : Member.DECLARED;
+ smgr.checkMemberAccess(tclass, type);
+ smgr.checkPackageAccess(tclass.getPackage().getName());
+ }
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
-
+
Class fieldt = field.getType();
if (fieldt != long.class)
throw new IllegalArgumentException("Must be long type");
-
- if (!Modifier.isVolatile(field.getModifiers()))
+
+ if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
-
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
this.tclass = tclass;
offset = unsafe.objectFieldOffset(field);
}
- public boolean compareAndSet(T obj, long expect, long update) {
+ private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
synchronized(this) {
long v = unsafe.getLong(obj, offset);
- if (v != expect)
+ if (v != expect)
return false;
unsafe.putLong(obj, offset, update);
return true;
@@ -298,20 +367,36 @@
}
public void set(T obj, long newValue) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
synchronized(this) {
unsafe.putLong(obj, offset, newValue);
}
}
+ public void lazySet(T obj, long newValue) {
+ set(obj, newValue);
+ }
+
public long get(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
synchronized(this) {
return unsafe.getLong(obj, offset);
}
}
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException (
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
}
}
-
Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java Tue Jul 28 09:30:33 2009
@@ -7,7 +7,7 @@
package java.util.concurrent.atomic;
/**
- * An <tt>AtomicMarkableReference</tt> maintains an object reference
+ * An {@code AtomicMarkableReference} maintains an object reference
* along with a mark bit, that can be updated atomically.
* <p>
* <p> Implementation note. This implementation maintains markable
@@ -31,7 +31,7 @@
private final AtomicReference<ReferenceBooleanPair<V>> atomicRef;
/**
- * Creates a new <tt>AtomicMarkableReference</tt> with the given
+ * Creates a new {@code AtomicMarkableReference} with the given
* initial values.
*
* @param initialRef the initial reference
@@ -61,10 +61,10 @@
/**
* Returns the current values of both the reference and the mark.
- * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>.
+ * Typical usage is {@code boolean[1] holder; ref = v.get(holder); }.
*
* @param markHolder an array of size of at least one. On return,
- * <tt>markholder[0]</tt> will hold the value of the mark.
+ * {@code markholder[0]} will hold the value of the mark.
* @return the current value of the reference
*/
public V get(boolean[] markHolder) {
@@ -76,12 +76,12 @@
/**
* Atomically sets the value of both the reference and mark
* to the given update values if the
- * current reference is <tt>==</tt> to the expected reference
- * and the current mark is equal to the expected mark. Any given
- * invocation of this operation may fail (return
- * <tt>false</tt>) spuriously, but repeated invocation when
- * the current value holds the expected value and no other thread
- * is also attempting to set the value will eventually succeed.
+ * current reference is {@code ==} to the expected reference
+ * and the current mark is equal to the expected mark.
+ *
+ * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+ * and does not provide ordering guarantees, so is only rarely an
+ * appropriate alternative to {@code compareAndSet}.
*
* @param expectedReference the expected value of the reference
* @param newReference the new value for the reference
@@ -93,7 +93,7 @@
V newReference,
boolean expectedMark,
boolean newMark) {
- ReferenceBooleanPair current = atomicRef.get();
+ ReferenceBooleanPair<V> current = atomicRef.get();
return expectedReference == current.reference &&
expectedMark == current.bit &&
((newReference == current.reference && newMark == current.bit) ||
@@ -105,8 +105,8 @@
/**
* Atomically sets the value of both the reference and mark
* to the given update values if the
- * current reference is <tt>==</tt> to the expected reference
- * and the current mark is equal to the expected mark.
+ * current reference is {@code ==} to the expected reference
+ * and the current mark is equal to the expected mark.
*
* @param expectedReference the expected value of the reference
* @param newReference the new value for the reference
@@ -118,7 +118,7 @@
V newReference,
boolean expectedMark,
boolean newMark) {
- ReferenceBooleanPair current = atomicRef.get();
+ ReferenceBooleanPair<V> current = atomicRef.get();
return expectedReference == current.reference &&
expectedMark == current.bit &&
((newReference == current.reference && newMark == current.bit) ||
@@ -134,16 +134,16 @@
* @param newMark the new value for the mark
*/
public void set(V newReference, boolean newMark) {
- ReferenceBooleanPair current = atomicRef.get();
+ ReferenceBooleanPair<V> current = atomicRef.get();
if (newReference != current.reference || newMark != current.bit)
atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark));
}
/**
* Atomically sets the value of the mark to the given update value
- * if the current reference is <tt>==</tt> to the expected
+ * if the current reference is {@code ==} to the expected
* reference. Any given invocation of this operation may fail
- * (return <tt>false</tt>) spuriously, but repeated invocation
+ * (return {@code false}) spuriously, but repeated invocation
* when the current value holds the expected value and no other
* thread is also attempting to set the value will eventually
* succeed.
@@ -153,7 +153,7 @@
* @return true if successful
*/
public boolean attemptMark(V expectedReference, boolean newMark) {
- ReferenceBooleanPair current = atomicRef.get();
+ ReferenceBooleanPair<V> current = atomicRef.get();
return expectedReference == current.reference &&
(newMark == current.bit ||
atomicRef.compareAndSet