java for循环执行太快会导致System.currentTimeMillis()重复

Java:我在使用System.currentTimeMillis()函数时遇到问题

我正在使用System.currentTimeMillis()在foor循环问题中生成唯一值,循环执行得太快,System.currentTimeMillis()给我重复值。

如何生成确定的唯一值。

for(int a=0;a<=10;a++){ System.out.println(System.currentTimeMillis()) } 

我也试过了,但它也不是生成唯一数字的特征

 System.currentTimeMillis()+Math.random() 

你为什么不使用System.nanoTime()

为什么不使用UUID库生成唯一标识符(已经在JDK http://download.oracle.com/javase/6/docs/api/java/util/UUID.html中 )。

或者更简单的方法:附加一个静态计数器

如果这是一个要求,我认为你的方法是错误的。

从理论上讲,无论计时器有多细粒度,机器都可以在比计时器粒度更短的时间内执行它。 在技​​术意义上依赖于这是真的是不正确的。

或者以另一种方式看待它 – 为什么你需要这些值是唯一的(你用它们是什么)? 如果你真的希望它们能够衡量它的执行时间,那么你应该很高兴在同一毫秒内发生的两次迭代得到了相同的值。

您是否考虑过使用静态,单调的计数器为每次执行中的每个迭代分配ID( AtomicLong对此很有用)? 像下面这样的东西很容易,没有并发问题:

 public class YourClass { private static final AtomicLong COUNTER = new AtomicLong(); private static nextId() { return COUNTER.getAndIncrement(); } // Rest of the class, which calls nextId() when it needs an identifier } 

如果您需要时序信息唯一性,那么这是两个单独的要求,那么为什么不使用由时间任意唯一ID组成的复合键?

答案很明显 – 得到一台较慢的电脑! 那么,或者使用System.nanoTime,如SO- System.currentTimeMillis vs System.nanoTime所述 。 但严重的是,除非你绝对必须,否则你不应该将时间用作唯一数字生成器。

使用系统时间的问题当然是:

  • 系统调用返回的时间向上舍入到比实际CPU时钟时间更高的精度。 如果您的ID生成代码运行速度超过此精度,那么您将发生冲突。
  • 如果您的代码是分布式的,并且每个工作单元都在生成ID,那么您会遇到ID冲突的可能性,因为单独的CPU或CPU核心使用其独立时钟分配ID。
  • 在Java这样的库中,实际上根据用户可设置的属性返回系统时间,无论出于何种原因,任何时候将日期重置为过去的某个时间段时,您都会遇到更多ID冲突的可能性。

生成唯一标识符的一个非常好的替代方法是利用不那么具有讽刺意义的通用唯一标识符 。 在各种语言中有多种实现,对于Java 5及更高版本,您可以使用UUID类。

编辑 :添加有关UUID的一些有用信息。

与@ Andrej的解决方案类似,但结合了计时器和计数器,因此如果重新启动应用程序,则不应重复编号。

 public enum IdGenerator { ; private static final AtomicLong COUNTER = new AtomicLong(System.currentTimeMillis()*1000); public static long nextId() { return COUNTER.getAndIncrement(); } } 

如果您仍想使用您的方法,您可以:

 for(int a=0;a<=10;a++){ Thread.sleep(1); System.out.println(System.currentTimeMillis()) } 

明确地让你的CPU变慢。

尝试Math.random()* System.currentTimeMillis()

这是一个样本结果

 4.1140390961236145E11, 4.405289623285403E11, 6.743938910583776E11, 2.0358542930175632E11, 1.2561886548511025E12, 8.629388909268735E11, 1.158038719369676E12, 2.5899667030405692E11, 7.815373208372445E11, 1.0887553507952611E12, 3.947241572203385E11, 1.6723200316764807E11, 1.3071550541162832E12, 2.079941126415029E11, 1.304485187296599E12, 3.5889095083604164E10, 1.3230275106525027E11, 6.484641777434403E11, 5.109822261418748E11, 1.2291750972884333E12, 8.972865957307518E11, 4.022754883048088E11, 7.997154244301389E11, 1.139245696210086E12, 2.633248409945871E11, 8.699957189419155E11, 9.487098785390422E11, 1.1645067228773708E12, 1.5274939161218903E11, 4.8470112347655725E11, 8.749120668472205E11, 2.435762445513599E11, 5.62884487469596E11, 1.1412787212758718E12, 1.0724213377031631E12, 3.1388106597100226E11, 1.1405727247661633E12, 1.2464739913912961E12, 3.2771161059896655E11, 1.2102869787179648E12, 1.168806596179512E12, 5.871383012375131E11, 1.2765757372075571E12, 5.868323434343102E11, 9.887351363037219E11, 5.392282944314777E11, 1.1926033895638833E12, 6.867917070018711E11, 1.1682059242674294E12, 2.4442056772643954E11, 1.1250254537683052E12, 8.875186600355891E10, 3.46331811747409E11, 1.127077925657995E12, 7.056541627184794E11, 1.308631075052609E12, 7.7875319089675E11, 5.52717019956371E11, 7.727797813063546E11, 6.177219592063667E11, 2.9448141585070874E11, 9.617992263836586E11, 6.762500987418107E11, 1.1954995292124463E12, 1.0741763597148225E12, 1.9915919731861673E11, 9.507720563185525E11, 1.1009594810160002E12, 4.1381256571745465E11, 2.2526550777831213E11, 2.5919816802026202E11, 3.8453225321522577E11, 3.796715779825083E11, 6.512277843921505E10, 1.0483456960599313E12, 1.0725956186588704E11, 5.701504883615902E11, 9.085583903150035E11, 1.2764816439306753E12, 1.033783414053437E12, 1.188379914238302E12, 6.42733442524156E11, 3.911345432964901E11, 7.936334657654698E11, 1.4473479058272617E11, 1.2030471387183499E12, 5.900668555531211E11, 8.078992189613184E11, 1.2004364275316113E12, 1.250275098717202E12, 2.856556784847933E11, 1.9118298791320355E11, 5.4291847597892596E11, 3.9527733898520874E11, 6.384539941791654E11, 1.2812873515441786E11, 6.325269269733575E9, 5.403119000792323E11, 8.023708335126083E11, 3.761680594623883E10, 1.2641772837928888E11, 

查看UUID也是……

我的建议

  long id = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { //do your work id++; }