使用ThreadLocalRandom产生并发随机数
2016-03-23 09:34
585 查看
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是每个线程一个实例,避免使用共享要引入同步。
相关文章推荐
- Java反射机制的学习(1)
- 把页面上的图表导出为pdf文件,分享一种请求下载文件的方法
- XAMARIN +VS2015 ANDROID 开发判断gps 是否打开。
- 网页实时刷新
- 架构安全 3/23/2016
- ASP.NET 使用Session,避免用户F5刷新时重复提交(转)
- Linux下实现软件的静默安装 debconf
- 解决Get和Post请求中中文乱码问题
- 机器学习简易入门(四)- logistic回归
- 为windows添加右键菜单
- 生产环境中centOS7最简版安装
- 在win7下安装IIS 7后打开自己的项目之后会出现500.19错误
- SharedPreferences方便存取工具类
- 当程序员面对小学数学题
- 哪些工具能有效管理Azure Active Directory?
- 使用cordova+Ionic+AngularJs进行Hybird App开发的环境搭建手册
- 使用CSS3 Media Queries实现网页自适应
- poj 1015 Jury Compromise 动态规划
- Redis开源代码读书笔记零(Ubuntu14.04 64位安装)
- unity3d中用2D背景当作图片