src/share/classes/java/util/concurrent/locks/LockSupport.java
Print this page
@@ -118,24 +118,13 @@
* }}</pre>
*/
public class LockSupport {
private LockSupport() {} // Cannot be instantiated.
- // Hotspot implementation via intrinsics API
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- private static final long parkBlockerOffset;
-
- static {
- try {
- parkBlockerOffset = unsafe.objectFieldOffset
- (java.lang.Thread.class.getDeclaredField("parkBlocker"));
- } catch (Exception ex) { throw new Error(ex); }
- }
-
private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
- unsafe.putObject(t, parkBlockerOffset, arg);
+ UNSAFE.putObject(t, parkBlockerOffset, arg);
}
/**
* Makes available the permit for the given thread, if it
* was not already available. If the thread was blocked on
@@ -147,11 +136,11 @@
* @param thread the thread to unpark, or {@code null}, in which case
* this operation has no effect
*/
public static void unpark(Thread thread) {
if (thread != null)
- unsafe.unpark(thread);
+ UNSAFE.unpark(thread);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
@@ -181,11 +170,11 @@
* @since 1.6
*/
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
- unsafe.park(false, 0L);
+ UNSAFE.park(false, 0L);
setBlocker(t, null);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
@@ -221,11 +210,11 @@
*/
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
- unsafe.park(false, nanos);
+ UNSAFE.park(false, nanos);
setBlocker(t, null);
}
}
/**
@@ -262,11 +251,11 @@
* @since 1.6
*/
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
- unsafe.park(true, deadline);
+ UNSAFE.park(true, deadline);
setBlocker(t, null);
}
/**
* Returns the blocker object supplied to the most recent
@@ -281,11 +270,11 @@
* @since 1.6
*/
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
- return unsafe.getObjectVolatile(t, parkBlockerOffset);
+ return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
@@ -310,11 +299,11 @@
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread upon return.
*/
public static void park() {
- unsafe.park(false, 0L);
+ UNSAFE.park(false, 0L);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
* the specified waiting time, unless the permit is available.
@@ -344,11 +333,11 @@
*
* @param nanos the maximum number of nanoseconds to wait
*/
public static void parkNanos(long nanos) {
if (nanos > 0)
- unsafe.park(false, nanos);
+ UNSAFE.park(false, nanos);
}
/**
* Disables the current thread for thread scheduling purposes, until
* the specified deadline, unless the permit is available.
@@ -378,8 +367,48 @@
*
* @param deadline the absolute time, in milliseconds from the Epoch,
* to wait until
*/
public static void parkUntil(long deadline) {
- unsafe.park(true, deadline);
+ UNSAFE.park(true, deadline);
}
+
+ /**
+ * Returns the pseudo-randomly initialized or updated secondary seed.
+ * Copied from ThreadLocalRandom due to package access restrictions
+ */
+ static final int nextSecondarySeed() {
+ int r;
+ Thread t = Thread.currentThread();
+ if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
+ r ^= r << 13; // xorshift
+ r ^= r >>> 17;
+ r ^= r << 5;
+ }
+ else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
+ r = 1; // avoid zero
+ UNSAFE.putInt(t, SECONDARY, r);
+ return r;
+ }
+
+ // Hotspot implementation via intrinsics API
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long parkBlockerOffset;
+ private static final long SEED;
+ private static final long PROBE;
+ private static final long SECONDARY;
+ static {
+ try {
+ UNSAFE = sun.misc.Unsafe.getUnsafe();
+ Class<?> tk = Thread.class;
+ parkBlockerOffset = UNSAFE.objectFieldOffset
+ (tk.getDeclaredField("parkBlocker"));
+ SEED = UNSAFE.objectFieldOffset
+ (tk.getDeclaredField("threadLocalRandomSeed"));
+ PROBE = UNSAFE.objectFieldOffset
+ (tk.getDeclaredField("threadLocalRandomProbe"));
+ SECONDARY = UNSAFE.objectFieldOffset
+ (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
}