1.ThreadLocalRandomԴ??
2.threadlocalrandom到底要怎么用
3.ThreadLo用
4.并发高的情况下,试试用ThreadLocalRandom来生成随机数
5.Java随机生成3个整数(1-6内),总和大于11就显示大,小于11就显示小
6.Java 生成随机数的 5 种方式,你知道几种?
ThreadLocalRandomԴ??
class RandomDemo
{
public static void main(String[] args)
{
int randomNum ;
while(true)
{
randomNum=(int)(Math.random()*);
if(randomNum%5==0)
{
System.out.println(randomNum);
break;
}
}
}
}
threadlocalrandom到底要怎么用
ThreadLocalRandom的使用方式 ThreadLocalRandom是Java中的一个实用工具类,用于在多线程环境中生成随机数。使用ThreadLocalRandom比使用传统的Random类在多线程并发情况下性能更优,因为它为每个线程提供了独立的在线源码随机数生成器,避免了多线程间的竞争和同步开销。下面是使用ThreadLocalRandom的简要步骤: 1. 导入ThreadLocalRandom类 在使用ThreadLocalRandom之前,需要先导入该类。可以在代码文件的开头添加以下导入语句: java import java.util.concurrent.ThreadLocalRandom; 2. 生成随机数 ThreadLocalRandom提供了多种生成随机数的方法,例如生成指定范围内的随机整数、随机浮点数等。以下是几个常用的方法: * 生成随机整数:`ThreadLocalRandom.current.nextInt` 可以生成一个范围在0到指定值之间的随机整数。 * 生成随机浮点数:`ThreadLocalRandom.current.nextFloat` 可以生成一个0.0到1.0之间的随机浮点数。 * 其他方法还包括生成随机长整型数、豆瓣网站源码随机布尔值等。 3. 在多线程环境中使用 由于ThreadLocalRandom为每个线程提供了独立的随机数生成器,因此在多线程环境下可以安全地使用。每个线程生成的随机数不会受到其他线程的影响,无需额外的同步措施。 详细解释 ThreadLocalRandom是Java 7引入的一个并发工具类,设计初衷是为了改善多线程环境下生成随机数的性能。在传统的Random类中,由于共享了随机数生成器的状态,多线程环境下可能会出现竞争和同步问题,导致性能下降。而ThreadLocalRandom通过将随机数生成器与线程绑定,确保每个线程都有自己的随机数生成器实例,从而避免了这些问题。场地预定源码 在使用ThreadLocalRandom时,可以通过静态方法`current`获取当前线程的随机数生成器实例,然后调用相应的方法生成随机数。由于每个线程都有自己的实例,因此无需担心多线程并发问题。这使得ThreadLocalRandom成为多线程应用中生成随机数的理想选择。ThreadLo用
改写后的文章如下:
云即服在JDK 7之后引入了ThreadLocalRandom,以解决多线程环境中随机数生成的竞争问题。与直接创建实例不同,ThreadLocalRandom采用静态方法current()首次使用。这种改变为并发环境带来了显著优势:它消除了多个线程共享单个随机数生成器实例的竞争,每个线程都拥有自己的实例。以下是对使用ThreadLocalRandom.current().nextDouble()与Math.random()进行的性能对比:使用Math.random()时,运行时间:毫秒
使用ThreadLocalRandom.current().nextDouble()时,社区源码下载运行时间:毫秒,提高了约%。
ThreadLocalRandom的例子类似于StringBuffer和StringBuilder,它们将线程安全性融入到初始化阶段,而非使用时,从而提高性能。同样,ThreadLocal和synchronized的使用也有异曲同工之妙:synchronized在代码使用时添加同步,而ThreadLocal则为每个线程创建独立实例,避免了对共享资源的同步需求,进一步优化了并发性能。并发高的情况下,试试用ThreadLocalRandom来生成随机数
一:简述如果我们想要生成一个随机数,通常会使用Random类。天天棋牌源码但是在并发情况下Random生成随机数的性能并不是很理想,今天给大家介绍一下JUC包中的用于生成随机数的类--ThreadLocalRandom.(本文基于JDK1.8)
二:Random的性能差在哪里
Random随机数生成是和种子seed有关,而为了保证线程安全性,Random通过CAS机制来保证线程安全性。从next()方法中我们可以发现seed是通过自旋锁和CAS来进行修改值的。如果在高并发的场景下,那么可能会导致CAS不断失败,从而导致不断自旋,这样就可能会导致服务器CPU过高。
protected?int?next(int?bits)?{ long?oldseed,?nextseed;AtomicLong?seed?=?this.seed;do?{ oldseed?=?seed.get();nextseed?=?(oldseed?*?multiplier?+?addend)?&?mask;}?while?(!seed.compareAndSet(oldseed,?nextseed));return?(int)(nextseed?>>>?(?-?bits));}复制代码三:ThreadLocalRandom的简单使用
使用的方法很简单,通过ThreadLocalRandom.current()获取到ThreadLocalRandom实例,然后通过nextInt(),nextLong()等方法获取一个随机数。
代码:
@Testvoid?test()?throws?InterruptedException?{ new?Thread(()->{ ThreadLocalRandom?random?=?ThreadLocalRandom.current();System.out.println(random.nextInt());}).start();new?Thread(()->{ ThreadLocalRandom?random?=?ThreadLocalRandom.current();System.out.println(random.nextInt());}).start();Thread.sleep();}复制代码运行结果:
四:为什么ThreadLocalRandom能在保证线程安全的情况下还能有不错的性能
我们可以看一下ThreadLocalRandom的代码实现。
首先我们很容易看出这是一个饿汉式的单例
/**?Constructor?used?only?for?static?singleton?*/private?ThreadLocalRandom()?{ initialized?=?true;?//?false?during?super()?call}/**?The?common?ThreadLocalRandom?*/static?final?ThreadLocalRandom?instance?=?new?ThreadLocalRandom();复制代码我们可以看到PROBE成员变量代表的是Thread类的threadLocalRandomProbe属性的内存偏移量,SEED成员变量代表的是Thread类的threadLocalRandomSeed属性的内存偏移量,SECONDARY成员变量代表的是Thread类的threadLocalRandomSecondarySeed属性的内存偏移量。
//?Unsafe?mechanicsprivate?static?final?sun.misc.Unsafe?UNSAFE;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;SEED?=?UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSeed"));PROBE?=?UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomProbe"));SECONDARY?=?UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSecondarySeed"));}?catch?(Exception?e)?{ throw?new?Error(e);}}复制代码可以看到Thread类中确实有这三个属性
Thread类:
@sun.misc.Contended("tlr")//当前Thread的随机种子?默认值是0long?threadLocalRandomSeed;/**?Probe?hash?value;?nonzero?if?threadLocalRandomSeed?initialized?*/@sun.misc.Contended("tlr")//用来标志当前Thread的threadLocalRandomSeed是否进行了初始化?0代表没有,非0代表已经初始化?默认值是0int?threadLocalRandomProbe;/**?Secondary?seed?isolated?from?public?ThreadLocalRandom?sequence?*/@sun.misc.Contended("tlr")//当前Thread的二级随机种子?默认值是0int?threadLocalRandomSecondarySeed;复制代码接下来我们看ThreadLocalRandom.current()方法。
ThreadLocalRandom.current()
ThreadLocalRandom.current()的作用主要是初始化随机种子,并且返回ThreadLocalRandom的实例。
首先通过UNSAFE类获取当前线程的Thread对象的threadLocalRandomProbe属性,看随机种子是否已经初始化。没有初始化,那么调用localInit()方法进行初始化
public?static?ThreadLocalRandom?current()?{ //?获取当前线程的if?(UNSAFE.getInt(Thread.currentThread(),?PROBE)?==?0)localInit();return?instance;}复制代码localInit()
localInit()方法的作用就是初始化随机种子,可以看到代码很简单,就是通过UNSAFE类对当前Thread的threadLocalRandomProbe属性和threadLocalRandomSeed属性进行一个赋值。
static?final?void?localInit()?{ int?p?=?probeGenerator.addAndGet(PROBE_INCREMENT);int?probe?=?(p?==?0)1?:?p;?//?skip?0long?seed?=?mix(seeder.getAndAdd(SEEDER_INCREMENT));Thread?t?=?Thread.currentThread();UNSAFE.putLong(t,?SEED,?seed);UNSAFE.putInt(t,?PROBE,?probe);}复制代码接下来以nextInt()方法为例,看ThreadLocalRandom是如何生成到随机数的。我们可以看出随机数正是通过nextSeed()方法获取到随机种子,然后通过随机种子而生成。所以重点看nextSeed()方法是如何获取到随机种子的。
public?int?nextInt(int?bound)?{ if?(bound?<=?0)throw?new?IllegalArgumentException(BadBound);int?r?=?mix(nextSeed());int?m?=?bound?-?1;if?((bound?&?m)?==?0)?//?power?of?twor?&=?m;else?{ ?//?reject?over-represented?candidatesfor?(int?u?=?r?>>>?1;?u?+?m?-?(r?=?u?%?bound)?<?0;?u?=?mix(nextSeed())?>>>?1);}return?r;}复制代码nextSeed()
nextSeed()方法的作用是获取随机种子,代码很简单,就是通过UNSAFE类获取当前线程的threadLocalRandomSeed属性,并且将原来的threadLocalRandomSeed加上GAMMA设置成新的threadLocalRandomSeed。
final?long?nextSeed()?{ Thread?t;?long?r;?//?read?and?update?per-thread?seedUNSAFE.putLong(t?=?Thread.currentThread(),?SEED,r?=?UNSAFE.getLong(t,?SEED)?+?GAMMA);return?r;}复制代码小结:
ThreadLocalRandom为什么线程安全?是因为它将随机种子保存在当前Thread对象的threadLocalRandomSeed变量中,这样每个线程都有自己的随机种子,实现了线程级别的隔离,所以ThreadLocalRandom也并不需要像Random通过自旋锁和cas来保证随机种子的线程安全性。在高并发的场景下,效率也会相对较高。
注:各位有没有发现ThreadLocalRandom保证线程安全的方式和ThreadLocal有点像呢
需要注意的点:
1.ThreadLocalRandom是单例的。
2.我们每个线程在获取随机数之前都需要调用一下ThreadLocalRandom.current()来初始化当前线程的随机种子。
3.理解ThreadLocalRandom需要对UnSafe类有所了解,它是Java提供的一个可以直接通过内存对变量进行获取和修改的一个工具类。java的CAS也是通过这个工具类来实现的。
原文:“/post/”
Java随机生成3个整数(1-6内),总和大于就显示大,小于就显示小
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class Q {
private final static ThreadLocalRandom generator = ThreadLocalRandom.current();
public static void main(String[] args) {
int summation = Σ(generate());
if(summation < )
System.out.printf("%d is less then %n", summation);
else
System.out.printf("%d is not less then %n", summation);
}
public static List<Integer> generate(){
return Arrays.asList(generator.nextInt(1, 7),generator.nextInt(1,7),generator.nextInt(1,7));
}
private static int Σ(final List<Integer> list){
int r = 0;
for(int i : list) r += i;
return r;
}
}
Java 生成随机数的 5 种方式,你知道几种?
本文将介绍五种Java生成随机数的方式,帮助你全面掌握随机数生成的技巧。
1. Math.random()静态方法
使用Math.random()方法可以生成0到1之间的随机double值。例如:
结果示例:
0., 0., 0., 0., 0., 0., 0., 0., 0., 0.
此方法通过java.util.Random类内部实现,确保了线程安全。
2. java.util.Random工具类
使用java.util.Random类提供的线性同余法伪随机数生成器(LGC)进行随机数生成。此方法存在可预测性问题,不适用于安全性要求高的场景。
使用示例:
结果示例:
-, -, -, ,
此方法使用当前系统时钟作为种子,保证了随机数生成的多样性。
3. java.util.concurrent.ThreadLocalRandom工具类
ThreadLocalRandom类提供了一种线程安全的随机数生成方式,适合并发环境。它基于java.util.Random类实现。
使用示例:
结果示例:
Thread-0: 0., Thread-1: 0., Thread-0: 0., Thread-1: 0.
ThreadLocalRandom确保了每个线程独立生成随机数,提高了并发效率。
4. java.Security.SecureRandom
SecureRandom类提供了安全性更高的随机数生成方式,适合用于安全敏感的应用场景。它基于操作系统提供的随机事件作为种子,如用户输入等。
使用示例:
结果示例:
!= , != , != -, != -, - !=
SecureRandom通过操作系统的随机事件产生种子,确保了随机数的不可预测性。
5. 随机字符串
可以使用Apache Commons-Lang库中的RandomStringUtils类生成随机字符串。通过Maven引入依赖。
RandomStringUtils类通过java.util.Random实现随机数生成,适用于需要生成随机字符串的场景。