src/share/classes/java/util/concurrent/locks/LockSupport.java
Print this page
*** 118,141 ****
* }}</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);
}
/**
* Makes available the permit for the given thread, if it
* was not already available. If the thread was blocked on
--- 118,130 ----
* }}</pre>
*/
public class LockSupport {
private LockSupport() {} // Cannot be instantiated.
private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
! 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,157 ****
* @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);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
--- 136,146 ----
* @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);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
*** 181,191 ****
* @since 1.6
*/
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! unsafe.park(false, 0L);
setBlocker(t, null);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
--- 170,180 ----
* @since 1.6
*/
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! UNSAFE.park(false, 0L);
setBlocker(t, null);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
*** 221,231 ****
*/
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! unsafe.park(false, nanos);
setBlocker(t, null);
}
}
/**
--- 210,220 ----
*/
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! UNSAFE.park(false, nanos);
setBlocker(t, null);
}
}
/**
*** 262,272 ****
* @since 1.6
*/
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! unsafe.park(true, deadline);
setBlocker(t, null);
}
/**
* Returns the blocker object supplied to the most recent
--- 251,261 ----
* @since 1.6
*/
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
! UNSAFE.park(true, deadline);
setBlocker(t, null);
}
/**
* Returns the blocker object supplied to the most recent
*** 281,291 ****
* @since 1.6
*/
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
! return unsafe.getObjectVolatile(t, parkBlockerOffset);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
--- 270,280 ----
* @since 1.6
*/
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
! return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
}
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
*** 310,320 ****
* 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);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
* the specified waiting time, unless the permit is available.
--- 299,309 ----
* 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);
}
/**
* Disables the current thread for thread scheduling purposes, for up to
* the specified waiting time, unless the permit is available.
*** 344,354 ****
*
* @param nanos the maximum number of nanoseconds to wait
*/
public static void parkNanos(long nanos) {
if (nanos > 0)
! unsafe.park(false, nanos);
}
/**
* Disables the current thread for thread scheduling purposes, until
* the specified deadline, unless the permit is available.
--- 333,343 ----
*
* @param nanos the maximum number of nanoseconds to wait
*/
public static void parkNanos(long nanos) {
if (nanos > 0)
! UNSAFE.park(false, nanos);
}
/**
* Disables the current thread for thread scheduling purposes, until
* the specified deadline, unless the permit is available.
*** 378,385 ****
*
* @param deadline the absolute time, in milliseconds from the Epoch,
* to wait until
*/
public static void parkUntil(long deadline) {
! unsafe.park(true, deadline);
}
}
--- 367,414 ----
*
* @param deadline the absolute time, in milliseconds from the Epoch,
* to wait until
*/
public static void parkUntil(long 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); }
+ }
+
}