在java中产生uuid的方式是使用java.util.UUID。

UUID.randomUUID().toString();

我在测试redis性能时,使用uuid产生测试数据,发现多线程测试redis的rpush接口的时候,性能老是上不去。 查看cpu利用率也不高,网卡流量也不大。就是tps上不去。但是如果用两台client去测,又可以达到更高的tps。

后来直接用jstack查看了下堆栈,发现大多数线程停留在:

java.lang.Thread.State: BLOCKED (on object monitor)
at java.security.SecureRandom.nextBytes(Unknown Source)
- waiting to lock <0x00000005ffe1c548> (a java.security.SecureRandom)
at java.util.UUID.randomUUID(Unknown Source)

原来uuid的生成遇到了性能瓶颈。于是我单独测试了下生成随机uuid的性能,发现无论是1个线程还是32个线程还是300个线程,它的tps只能到10万级别。 甚至是线程数越大,tps越低。tps在每个机器上都不一样,有的机器上测试tps只有5万。我们就以一台双核4G内存的虚拟机为例:

tps在 140000+

我们看randomUUID方法的javadoc的描述是: The UUID is generated using a cryptographically strong pseudo random number generator 也就是说uuid使用了一个强随机数,也也保证了uuid的不重复性。

public static UUID randomUUID() {
SecureRandom ng=numberGenerator;
if(ng == null)
numberGenerator=ng=new SecureRandom();
 
byte[] randomBytes=new byte[16];
ng.nextBytes(randomBytes);
return new UUID(randomBytes);
}

再看SecureRandom的javadoc Note: Depending on the implementation, the generateSeed and nextBytes methods may block as entropy is being gathered, for example, if they need to read from /dev/random on various unix-like operating systems.

也就是说SecureRandom的nextBytes方法,依赖随机数的产生,如果随机数不够了,它有可能就会堵塞在那边。 比如随机数的产生是读取unix类系统的/dev/random文件。

我们再去看有关/dev/random的信息:

Linux中的随机数可以从两个特殊的文件中产生,一个是/dev/urandom.另外一个是/dev/random。他们产生随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。如果当前环境噪音变化的不是很剧烈或者当前环境噪音很小,比如刚开机的时候,而当前需要大量的随机比特,这时产生的随机数的随机效果就不是很好了。

这就是为什么会有/dev/urandom和/dev/random这两种不同的文件,后者在不能产生新的随机数时会阻塞程序,而前者不会(ublock),当然产生的随机数效果就不太好了,这对加密解密这样的应用来说就不是一种很好的选择。/dev/random会阻塞当前的程序,直到根据熵池产生新的随机字节之后才返回,所以使用/dev/random比使用/dev/urandom产生大量随机数的速度要慢。

jdk默认的是读取/dev/random文件产生强随机数,但是如果不是为了产生加密随机数,我们可以设置jdk读取/dev/urandom产生随机数,从而生成随机uuid。

在java启动项中增加-Djava.security.egd=file:/dev/./urandom 配置项(不能写作/dev/urandom,关于这个,网上有相关八卦历史~)

再去相同的机器上测试uuid的性能:

tps在 720000+

java uuid第一次性能的更多相关文章

  1. 如何利用缓存机制实现JAVA类反射性能提升30倍

    一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> ...

  2. 用于快速排查Java的CPU性能问题(top us值过高)

    转载于GIT路径 https://github.com/oldratlee/useful-scripts/blob/master/docs/java.md#beer-show-busy-java-th ...

  3. Java MVC框架性能比较

    Java MVC框架性能比较 - by zvane 现在各种MVC框架很多,各框架的优缺点网络上也有很多的参考文章,但介绍各框架性能方面差别的文章却不多,本人在项目开发中,感觉到采用了struts2框 ...

  4. jvm 命令使用调优 通过jstat、jmap对java程序进行性能调优

    转载:http://blog.csdn.net/jerry024/article/details/8507589 转载: https://blog.csdn.net/zhaozheng7758/art ...

  5. lua、groovy嵌入到java中的性能对比(转)

    lua和groovy都是可以嵌入到java中的脚本语言.lua以高性能著称,与C/C++在游戏开放中有较多使用,groovy是一个基于Java虚拟机(JVM)的敏捷动态语言,在jvm下有着不错的性能. ...

  6. java UUID的创建

    java UUID的创建: 参考:http://blog.csdn.net/yaerfeng/article/details/7070369 可以研究一下最后的一段代码: http://spiritf ...

  7. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  8. 性能调优之Java系统级性能监控及优化

    性能调优之Java系统级性能监控及优化   对于性能调优而言,通常我们需要经过以下三个步骤:1,性能监控:2,性能剖析:3,性能调优 性能调优:通过分析影响Application性能问题根源,进行优化 ...

  9. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

随机推荐

  1. 0005_Linux下的SSH连接操作

    1.启动SSH服务:service sshd start 2.开机自动启动SSH:chkconfig sshd on 3.获取Linux的ip地址:ifconfig 4.连接Linux的SSH:打开x ...

  2. nohup开机自启脚本

    #!/bin/bash cd /root/xcloud/ str=$"/n" sstr=$(echo -e $str) nohup ./deploy >>/dev/nu ...

  3. QTableWidget笔记

    1.QTableWidget继承自QTableView. 2.头文件:QTableWidget 3.简单使用: #include "mainwindow.h" #include & ...

  4. SLAM细碎内容积累_来自各种技术交流群_持续更新

    imu标定 工具包:imu_utils,   imu_tk,   kalibr 用kalibr做标定,相机和imu的采样频率要求:相机20,imu100.kalibr也可以做鱼眼相机+imu的联合标定 ...

  5. c# sleep 例子-线程挂起

    using System; using System.Threading; public class arr { public static void Main() { //int[] arr; // ...

  6. HRBUST - 1214 NOIP2000提高组 方格取数(多线程dp)

    方格取数 设有N*N的方格图(N<=10),我们将其中的某些方格中填入正整数,而其他的方格中则放人数字0.如下图所示(见样例 ,黄色和蓝色分别为两次走的路线,其中绿色的格子为黄色和蓝色共同走过的 ...

  7. Python开发【第四篇】:运算符

      1. 算术运算符   算术运算符包括+.-.*./.%.//.**,即加减乘除,取余,取商(地板除法)以及幂运算. >>> 5 + 2 7 >>> 5 - 2 ...

  8. 51nod1105(二分)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105 题意:中文题诶- 思路:直接二分答案,再通过二分找有多少 ...

  9. uoj#290. 【ZJOI2017】仙人掌(数数+仙人掌+树形dp)

    传送门 这图可以说是非常形象了2333 模拟赛的时候打了个表发现为一条链的时候答案是\(2^{n-2}\)竟然顺便过了第一个点 然后之后订正的时候强联通分量打错了调了一个上午 首先不难发现我们可以去掉 ...

  10. [Xcode 实际操作]六、媒体与动画-(17)使用MediaPlayer框架播放视频

    目录:[Swift]Xcode实际操作 本文将演示视频的播放功能. 在项目名称上点击鼠标右键,弹出右键菜单, 选择[Add Files to "DemoApp"],往项目中导入文件 ...