java多线程threadlocal,java多线程继承Thread类
00-1010为什么需要详细解释ThreadLocalRandomThreadRandom原理
目录
java.util.Random一直是随机数生成广泛使用的工具类,java.lang.Math中的随机数生成也是java.util.Random使用的实例。
我们下面看一下java.util.Random的使用方法:
导入Java . util . random;public class code _ 4 _ thread Random { public static void main(String[]args){ Random Random=new Random();for(int I=0;i 10I){ system . out . println(random . nextint(5));}}}随机数的生成需要一个默认种子。这个种子是一个long类型的数字,可以由构造函数在创建随机对象时指定。如果未指定,将在默认构造函数中生成默认值。
Public int nextInt(int bound) {//参数检查if (bound=0)抛出新的illegalargumentexception(错误的界限);//根据旧种子生成新种子int r=next(31);int m=bound-1;如果((bound m)==0)//即bound是2的幂//根据新的种子生成新的随机数r=(int)((bound *(long)r)31);else { for(int u=r;u-(r=u % bound)m 0;u=next(31);} return r;}从上面的代码可以看出,新随机数的生成需要两步:首先根据旧种子生成新种子,然后根据新种子计算新随机数。如果在单线程的情况下,每次调用nextInt都会根据旧种子计算一个新种子。但是,在多线程下,多个线程可能都获得相同的旧种子来生成新种子。这一次,多个线程生成的新随机数是相同的。我们需要当多个线程通过同一个旧种子计算新种子时,在计算第一个线程的新种子时,第二个线程要丢弃旧种子,用第一个线程计算的新种子计算自己的新种子。在Random类中,对象初始化时的种子保存在种子原子变量中。
下面看一下next()的代码:
protected int next(int bits){ long old seed,nextseedAtomicLong seed=this.seeddo { old seed=seed . get();nextseed=(oldseed *乘数加数)掩码;} while(!seed.compareAndSet(oldseed,next seed));return (int)(nextseed (48位));}在上面的代码中,种子是通过CAS操作更新的。在多线程的情况下,多个线程同时计算随机数来计算新的种子。多个线程会争用同一个原子变量的更新操作,会造成大量线程自旋重试,降低并发性能。于是ThreadLocalRandom应运而生。
为什么需要ThreadLocalRandom
导入Java . util . random;public class code _ 4 _ threadlocalrrandom { public static void main(String[]args){ Random Random=new threadlocalrrandom . current();for(int I=0;i 10I){ system . out . println(random 1 . nextint(5));}}}如果每个线程都维护一个种子变量,那么每个线程在生成随机数时都会根据自己的旧种子计算一个新种子,用新种子更新旧种子,然后根据新种子计算随机数,这样就不会出现竞争问题。ThreadLocalRandom类继承了Random类并重写了nextlnt方法。在ThreadLocalRandom类中,不使用从Random类继承的原子种子变量。
ThreadLocalRandom中没有存储特定的种子,但是特定的种子存储在特定调用线程的threadLocalRandomSeed变量中。ThreadLocalRandom类似于ThreadLocal类,是一个工具类。当线程调用ThreadLocalRandom的当前方法时,ThreadLocalRandom负责初始化调用线程的threadLocalRandomSeed变量,该变量是初始化种子。使用ThreadLocalRandom的nextInt方法时,实际上是将当前线程的threadLocalRandomSeed变量作为当前种子计算新种子,然后将新种子更新为当前线程的threadLocalRandomSeed变量,再根据新种子和具体算法计算随机数。这里需要注意的是,threadLocalRandomSeed变量是Thread类中一个普通的long变量,不是原子变量。其实原因很简单,因为这个变量是线程级的,所以根本不需要使用原子变量。
变量实例是ThreadLocalRandom的实例,它是静态的。多线程通过ThreadLocalRandom的当前方法获取ThreadLocalRandom的实例时,实际上是同一个实例。但由于具体种子存储在线程中,ThreadLocalRandom的实例只包含与线程无关的通用算法,所以是线程安全的。
以上就是本文对Java并发编程ThreadLocalRandom类的详细解释。关于Java ThreadLocalRandom的更多信息,请搜索Popular IT之前的文章或者继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。