在Java 8中,java.lang.Thread
类有3个新字段:
/** The current seed for a ThreadLocalRandom */ @sun.misc.Contended("tlr") long threadLocalRandomSeed; /** Probe hash value; nonzero if threadLocalRandomSeed initialized */ @sun.misc.Contended("tlr") int threadLocalRandomProbe; /** Secondary seed isolated from public ThreadLocalRandom sequence */ @sun.misc.Contended("tlr") int threadLocalRandomSecondarySeed;
正如它在Javadoc中所说的那样是由专门管理的java.util.concurrent.ThreadLocalRandom
.
此外,ThreadLocalRandom
它们以非常奇特的方式使用:
SEED = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomSeed")); PROBE = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomProbe")); SECONDARY = UNSAFE.objectFieldOffset (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
(同样的代码片也可以在LockSupport
课堂上得到满足).
然后这个偏移在几个java.concurrent
地方内部使用.
这个想法是什么?为什么这些字段在里面java.lang.Thread
?为什么不在里面ThreadLocalRandom
?
这些是内部字段.解释只能来自JDK开发人员自己.我从2013年1月的Doug Lea 那里找到了一篇关于这个的帖子,这个帖子解释了这些领域背后的理由以及为什么他们在Thread
课堂上.
当我们介绍时
ThreadLocalRandom
,我们保守地实现它以使用实际ThreadLocal
.然而,随着它的使用越来越广泛,通过ThreadLocalRandom
在课堂上容纳州(和相关的簿记)来改善实施是值得的Thread
.这将需要三个字段(总共16个字节).所以我建议在Thread类中添加以下内容:
// The following three initially uninitialized fields are exclusively // managed by class java.util.concurrent.ThreadLocalRandom. /** The current seed for a ThreadLocalRandom */ long threadLocalRandomSeed; /** Probe hash value; nonzero if threadLocalRandomSeed initialized */ int threadLocalRandomProbe; /** Secondary seed isolated from public ThreadLocalRandom sequence */ int threadLocalRandomSecondarySeed;这样做的原因是:
一致更快地进入
ThreadLocalRandom
州.虽然ThreadLocal
访问通常已经非常快,但这不仅更快,而且在用户程序创建大量ThreadLocal
s的情况下不会降低,这可能(概率上)导致任何给定访问变慢.任何程序使用的总占用空间都较小
ThreadLocalRandom
.三个字段比装入填充ThreadLocal
对象所需的空间更少 .随着ThreadLocalRandom
JDK本身的广泛使用,这几乎包括所有程序.而且时间/空间节省
java.util.concurrent ForkJoinPool
,ConcurrentHashMap
,LongAdder
,ConcurrentSkipList
,和可以使用这种形式的统一的其他类ThreadLocalRandom
簿记,而不是他们自己的专用ThreadLocal
S作为他们现在要做的.