前言
相关系列
- 《Java & Lock & 目录》(持续更新)
- 《Java & Lock & LockSupport & 源码》(学习过程/多有漏误/仅作参考/不再更新)
- 《Java & Lock & LockSupport & 总结》(学习总结/最新最准/持续更新)
- 《Java & Lock & LockSupport & 问题》(学习解答/持续更新)
源码
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package juc.locks;
import juc.Semaphore;
import sun.misc.Unsafe;
import java.util.concurrent.ThreadLocalRandom;
/**
* Basic thread blocking primitives for creating locks and other synchronization classes.
* 用于创建锁和其它同步类的基本线程阻塞原语。
* <p>
* This class associates, with each thread that uses it, a permit (in the sense of the
* {@link Semaphore Semaphore} class). A call to {@code park} will return immediately if the permit is available,
* consuming it in the process; otherwise it <em>may</em> block. A call to {@code unpark} makes the permit available,
* if it was not already available. (Unlike with Semaphores though, permits do not accumulate. There is at most one.)
* 该类与每个使用它的线程关联一个许可(从信号量类的角度上看)。如果许可可用则调用一次park()方法将立即返回,并
* 在过程中消费它;否则它将可能阻塞。如果许可不可用,则调用一次unpark()方法可使得其可用。(但是不像信号量,许
* 可无法累积。最多只能有一个。)
* <p>
* Methods {@code park} and {@code unpark} provide efficient means of blocking and unblocking threads that do not
* encounter the problems that cause the deprecated methods {@code Thread.suspend} and {@code Thread.resume} to
* beunusable for such purposes: Races between one thread invoking {@code park} and another thread trying to
* {@code unpark} it will preserve liveness, due to the permit. Additionally, {@code park} will return if the caller's
* threadwas interrupted, and timeout versions are supported. The {@code park} method may also return at any other
* time, for "no reason", so in general must be invoked within a loop that rechecks conditions upon return. In this sense
* {@code park}serves as an optimization of a "busy wait" that does not waste as much time spinning, but must be
* paired with an {@code unpark} to be effective.
* 方法park和unpark提供了阻塞和解除阻塞线程的有效方法,这些方法不会遇到导致已弃用方法suspend和resume对于如此
* 目的无用的问题:在线程调用park方法与其它线程尝试unpark它之间竞争将由于许可而保持活性。此外,如果调用者的线
* 程已被中断,以及支持超时版本则park将返回。park方法也可能在任意其它时间无理由的返回,所以通常必须在返回后检
* 查条件的循环中被调用。从这个角度上看park方法作为忙等待的优化手段不会浪费太多自旋时间,但必须与一个unpark方
* 法成对使用以令之有效。
* <p>
* The three forms of {@code park} each also support a {@code blocker} object parameter. This object is recorded while
* the thread is blocked to permit monitoring and diagnostic tools to identify the reasons that threads are blocked. (Such
* tools may access blockers using method {@link #getBlocker(Thread)}.) The use of these forms rather than the original
* forms without this parameter is strongly encouraged. The normal argument to supply as a {@code blocker} within a
* lock implementation is {@code this}.
* park方法的三种格式每个都支持一个阻塞者对象参数。该对象在线程在线程阻塞期间被记录,以允许监视器和诊断工具识
* 别线程阻塞的原因。(该工具可能访问使用getBlocker(Thread)方法访问阻塞者)。强烈鼓励使用这些格式而不是原本没有
* 参数的原始格式。该常规参数用于在一个锁实现中供应一个阻塞者。
* <p>
* These methods are designed to be used as tools for creating higher-level synchronization utilities, and are not in
* themselves useful for most concurrency control applications. The {@code park} method is designed for use only in
* constructions of the form:
* 这些方法被设计用于作为创建更高等级的同步程序的工具,并且它们本身对于大多数并发控制应用程序并没有用(意思是
* 不会在API中使用相应的方法保证线程安全,而是使用基于它们创建的线程安全工具保证线程安全)。park方法被设计只在
* 以下格式中构造:
* <pre> {@code
* while (!canProceed()) { ... LockSupport.park(this); }}</pre>
* <p>
* where neither {@code canProceed} nor any other actions prior to the call to {@code park} entail locking or blocking.
* Because only one permit is associated with each thread, any intermediary uses of {@code park} could interfere with
* its intended effects.
* 其中即不是canProceed方法也不是任意其它优先于park方法的活动都需要加锁或阻塞(意思是循环中位于park方法之后的
* 代码都必须是线程安全的...妈的什么鬼英语)。因为线程只关联一个许可,因此任意park方法的中间调用都会干涉它的预
* 期效果(简而言之就是要要避免外部干扰)。
*
* <p>
* <b>Sample Usage.</b> Here is a sketch of a first-in-first-out non-reentrant lock class:
* 简单用法。这是一个先入先出非重入锁类的草图:
* <pre> {@code
* class FIFOMutex {
* // ---- 原子布尔,作为锁使用。
* private final AtomicBoolean locked = new AtomicBoolean(false);
* // ---- 等待者队列。
* private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
*
* // ---- 加锁。
* public void lock() {
* // ---- 经线程加入等待者集中。
* boolean wasInterrupted = false;
* Thread current = Thread.currentThread();
* waiters.add(current);
*
* // Block while not first in queue or cannot acquire lock
* // 在非队列首个线程或无法获取锁的情况下阻塞
*
* while (waiters.peek() != current || !locked.compareAndSet(false, true)) {
* LockSupport.park(this);
* if (Thread.interrupted())
* // ignore interrupts while waiting
* // 忽略在等待期间的中断(即该方法在设计上是不允许被中断的)
* wasInterrupted = true;
* }
* // ---- 退出循环后,将当前线程从等待者集中移除。
* waiters.remove();
* // reassert interrupt status on exit
* // 在退出时重设中断状态。
* if (wasInterrupted)
* current.interrupt();
* }
*
* public void unlock() {
* locked.set(false);
* // ---- 唤醒等待者集中的首个线程。
* LockSupport.unpark(waiters.peek());
* }
* }}</pre>
*/
public class LockSupport {
/**
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* ----
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 初始化锁支持者
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ----
*/
private LockSupport() {
// Cannot be instantiated.
// 无法(外部)实例化
}
/**
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 设置阻塞者
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 为指定线程设置指定阻塞者
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法直接通过CAS操作完成。
*/
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
* {@code park} then it will unblock. Otherwise, its next call to {@code park} is guaranteed not to block. This
* operation is not guaranteed to have any effect at all if the given thread has not been started.
* 如果指定线程尚未可用,则令其许可可用。如果线程它因为park方法而阻塞则它将解除阻塞。否则,它的下次park方
* 法调用将不保证阻塞。如果指定线程尚未启动则该操作无法保证在任意情况下都有效果。
*
* @param thread the thread to unpark, or {@code null}, in which case this operation has no effect
* 用于释放的线程,或者为null,在该情况下该操作没有效果
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 解除停放
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 为指定线程分配一个许可,如果指定线程因为许可负债(-1)而处于等待状态,则将因为负债被清零而恢复运行;如果
* 指定线程因为许可平衡(0)而处于运行状态,则将因为许可结余(1)而不会在下一次许可消耗中进入等待状态。如果
* 执行线程尚未启动则上述所有情况都不保证一定会发生。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法直接通过CAS机制实现。
*/
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.
* 出于线程调度目的令当前线程无效,除非许可可用。
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of three things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下三种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* <p>
* This method does <em>not</em> report which of these caused the 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.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态。
*
* @param blocker the synchronization object responsible for this thread parking
* 该同步对象负责当前线程的停泊
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入无限等待状态;直至因为信号、中断及虚假的原
* 因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返
* 回。阻塞者的作用是令唤醒当前线程可以判断是否满足条件,功能是自定义的。
* @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 the specified waiting time, unless the permit
* is available.
* 出于调度线程的目的令当前线程无效,直至指定等待时间,除非许可可用。
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of four things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The specified waiting time elapses; or
* 指定等待时间消逝;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* </ul>
*
* <p>
* This method does <em>not</em> report which of these caused the 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, or the elapsed time upon return.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态,或过期时间。
*
* @param blocker the synchronization object responsible for this thread parking
* 该同步对象负责当前线程的停泊
* @param nanos the maximum number of nanoseconds to wait
* 等待的最大纳秒时间
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊纳秒
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚
* 假的原因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法首先会判断指定等待时间是否合法,合法则为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进
* 入等待状态失败则将阻塞者清除并返回。
* @since 1.6
*/
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);
}
}
/**
* Disables the current thread for thread scheduling purposes, until the specified deadline, unless the permit is available.
* 出于调度线程的目的令当前线程无效,直至指定死亡线,除非许可可用。
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of four things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The specified waiting time elapses; or
* 指定等待时间消逝;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* </ul>
* <p>
* This method does <em>not</em> report which of these caused the 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, or the current time upon return.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态,或过期时间。
*
* @param blocker the synchronization object responsible for this thread parking
* 该同步对象负责当前线程的停泊
* @param deadline the absolute time, in milliseconds from the Epoch, to wait until
* 从纪元到等待的绝对时间,以毫秒为单位
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊直至
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚
* 假的原因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返
* 回。
* @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 invocation of a park method that has not yet unblocked, or
* null if not blocked. The value returned is just a momentary snapshot -- the thread may have since unblocked or
* blocked on a different blocker object.
* 返回由最近一次还未解除阻塞的park方法调用提供的阻塞者对象,或者如果未阻塞则为null。返回的值只是一个短暂的
* 快照-- 该线程可能已解除阻塞或在另一个阻塞对象中阻塞。
*
* @param t the thread 线程
* @return the blocker 阻塞者
* @throws NullPointerException if argument is null
* 空指针异常:如果参数为null
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 获取阻塞者
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 获取当前线程的阻塞者。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ----
* @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.
* 出于线程调度目的令当前线程无效,除非许可可用。
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of three things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下三种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* </ul>
*
* <p>
* This method does <em>not</em> report which of these caused the 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.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态。
*
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入无限等待状态;直至因为信号、中断及虚假的原
* 因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ----
*/
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.
* 出于调度线程的目的令当前线程无效,直至指定等待时间,除非许可可用。
*
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of four things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The specified waiting time elapses; or
* 指定等待时间消逝;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* </ul>
*
* <p>
* This method does <em>not</em> report which of these caused the 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, or the elapsed time upon return.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态,或过期时间。
*
* @param nanos the maximum number of nanoseconds to wait
* 等待的最大纳秒时间
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊纳秒
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚
* 假的原因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ----
*/
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.
* 出于调度线程的目的令当前线程无效,直至指定死亡线,除非许可可用。
* <p>
* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes
* disabled for thread scheduling purposes and lies dormant until one of four things happens:
* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:
* <ul>
* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or
* 某些其它线程将当前线程作为目标调用unpark方法;或者
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or
* 某些其它线程中断当前线程;或者
* <li>The specified waiting time elapses; or
* 指定等待时间消逝;或者
* <li>The call spuriously (that is, for no reason) returns. </ul>
* 该调用虚假地(无理由地)返回。
* </ul>
* <p>
* This method does <em>not</em> report which of these caused the 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, or the current time upon return.
* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,
* 例如,线程返回后的中断状态,或过期时间。
*
* @param deadline the absolute time, in milliseconds from the Epoch, to wait until
* 从纪元到等待的绝对时间,以毫秒为单位
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 停泊直至
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚
* 假的原因而唤醒;否则直接返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返
* 回。
*/
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.
* 虚假随机地返回初始化的或更新的次要个种子。由于包访问限制从ThreadLocalRandom中赋值。
*
* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------
* 下个次要种子
* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------
* 基于当前线程的次要种子生成新的次要种子并保存/返回。
* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------
* ---- 方法首先会从当前线程中获取次要种子并判断是否为0,为0表示为初始值,为之随机分配一个值。但为了防止随机
* 的数值为0需要在该情况下手动将之赋值为1;如果不为0则说明次要种子已经被更新过,基于其进行位运算已生成新的
* 次要种子。
* ---- 新的次要种子生成后将之重新保存至当前线程中并返回。
*/
static final int nextSecondarySeed() {
int r;
Thread t = Thread.currentThread();
if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
// ---- 从线程中获取次要种子,如果不为0,说明已经经历过更新,直接进行位操作。
r ^= r << 13; // xorshift
r ^= r >>> 17;
r ^= r << 5;
} else if ((r = ThreadLocalRandom.current().nextInt()) == 0)
// avoid zero
// 避免0
// ---- 如果次要种子为0,说明为初始值,尚未经历过更新,因此为之分配一个随机数。但是为了防止其再次为0需
// 要在其位0是手动赋值为1。
r = 1;
// ---- 新的次要种子被分配后,重新保存。
UNSAFE.putInt(t, SECONDARY, r);
return r;
}
// Hotspot implementation via intrinsics API
private static final 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 = 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);
}
}
}