java7新特性——使用ThreadLocalRandom产生并发随机数

Java 7之前我们使用Math.random()产生随机数,使用原子变量来保存当前的种子,这样两个线程同时调用序列时得到的是伪随机数,而不是相同数量的两倍。

ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。ThreadLocalRandom不是直接用new实例化,而是第一次使用其静态方法current()。

从Math.random()改变到ThreadLocalRandom有如下好处:

我们不再有从多个线程访问同一个随机数生成器实例的争夺。

取代以前每个随机变量实例化一个随机数生成器实例,我们可以每个线程实例化一个。

代码改变如下:

// Random random = new Random(100);  random1.nextDouble();
double u = ThreadLocalRandom.current().nextDouble();

性能对比

使用Math.random()的结果如下:

StopWatch 'Monte Carlo NPV': running time (millis) = 44637
-----------------------------------------
ms % Task name
-----------------------------------------
12202 027% Sequential
02576 006% DivideByTwo (children=2, min fork size=100)
02465 006% DivideByTwo (children=2, min fork size=500)
02615 006% DivideByTwo (children=2, min fork size=1000)
02515 006% DivideByTwo (children=2, min fork size=2000)
02502 006% DivideByP (children=8, min fork size=100)
02490 006% DivideByP (children=8, min fork size=500)
02445 005% DivideByP (children=8, min fork size=1000)
02450 005% DivideByP (children=8, min fork size=2000)
02477 006% Sqrt(n) (children=-1, min fork size=100)
02458 006% Sqrt(n) (children=-1, min fork size=500)
02466 006% Sqrt(n) (children=-1, min fork size=1000)
02468 006% Sqrt(n) (children=-1, min fork size=2000)
02508 006% Parfor (children=20000, min fork size=500)

使用ThreadLocalRandom.current().nextDouble()结果:

StopWatch 'Monte Carlo NPV': running time (millis) = 34942
-----------------------------------------
ms % Task name
-----------------------------------------
11347 032% Sequential
02004 006% DivideByTwo (children=2, min fork size=100)
01831 005% DivideByTwo (children=2, min fork size=500)
01838 005% DivideByTwo (children=2, min fork size=1000)
01784 005% DivideByTwo (children=2, min fork size=2000)
01781 005% DivideByP (children=8, min fork size=100)
01782 005% DivideByP (children=8, min fork size=500)
01772 005% DivideByP (children=8, min fork size=1000)
01776 005% DivideByP (children=8, min fork size=2000)
01781 005% Sqrt(n) (children=-1, min fork size=100)
01788 005% Sqrt(n) (children=-1, min fork size=500)
01805 005% Sqrt(n) (children=-1, min fork size=1000)
01799 005% Sqrt(n) (children=-1, min fork size=2000)
01854 005% Parfor (children=20000, min fork size=500)

足足提高了25%。

正如StringBuffer和StingBuilder一样,通过将线程安全放入其初始化部分,而不是在使用阶段,这就能够得到性能提升,另外一个例子是ThreadLocal和synchronized,synchronized是在代码使用时加上同步,而使用ThreadLocal是每个线程一个实例,避免使用共享要引入同步。

  
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值