jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java
changeset 39934 9c84ee88dd3a
parent 39933 c0dd0f198453
parent 39922 e613affb88d1
child 39935 6016bd47edc9
equal deleted inserted replaced
39933:c0dd0f198453 39934:9c84ee88dd3a
     1 /*
       
     2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 import org.testng.Assert;
       
    25 import org.testng.annotations.Test;
       
    26 
       
    27 import java.util.concurrent.ThreadLocalRandom;
       
    28 import java.util.concurrent.atomic.AtomicInteger;
       
    29 import java.util.concurrent.atomic.LongAdder;
       
    30 import java.util.function.BiConsumer;
       
    31 
       
    32 import static org.testng.Assert.*;
       
    33 
       
    34 /**
       
    35  * @test
       
    36  * @bug 8024253
       
    37  * @run testng ThreadLocalRandomTest
       
    38  * @run testng/othervm -Djava.util.secureRandomSeed=true ThreadLocalRandomTest
       
    39  * @summary test methods on ThreadLocalRandom
       
    40  */
       
    41 @Test
       
    42 public class ThreadLocalRandomTest {
       
    43 
       
    44     // Note: this test was copied from the 166 TCK ThreadLocalRandomTest test
       
    45     // and modified to be a TestNG test
       
    46 
       
    47     /*
       
    48      * Testing coverage notes:
       
    49      *
       
    50      * We don't test randomness properties, but only that repeated
       
    51      * calls, up to NCALLS tries, produce at least one different
       
    52      * result.  For bounded versions, we sample various intervals
       
    53      * across multiples of primes.
       
    54      */
       
    55 
       
    56     // max numbers of calls to detect getting stuck on one value
       
    57     static final int NCALLS = 10000;
       
    58 
       
    59     // max sampled int bound
       
    60     static final int MAX_INT_BOUND = (1 << 28);
       
    61 
       
    62     // max sampled long bound
       
    63     static final long MAX_LONG_BOUND = (1L << 42);
       
    64 
       
    65     // Number of replications for other checks
       
    66     static final int REPS = 20;
       
    67 
       
    68     /**
       
    69      * setSeed throws UnsupportedOperationException
       
    70      */
       
    71     @Test(expectedExceptions = UnsupportedOperationException.class)
       
    72     public void testSetSeed() {
       
    73         ThreadLocalRandom.current().setSeed(17);
       
    74     }
       
    75 
       
    76     /**
       
    77      * Repeated calls to nextInt produce at least two distinct results
       
    78      */
       
    79     public void testNextInt() {
       
    80         int f = ThreadLocalRandom.current().nextInt();
       
    81         int i = 0;
       
    82         while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
       
    83             ++i;
       
    84         assertTrue(i < NCALLS);
       
    85     }
       
    86 
       
    87     /**
       
    88      * Repeated calls to nextLong produce at least two distinct results
       
    89      */
       
    90     public void testNextLong() {
       
    91         long f = ThreadLocalRandom.current().nextLong();
       
    92         int i = 0;
       
    93         while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
       
    94             ++i;
       
    95         assertTrue(i < NCALLS);
       
    96     }
       
    97 
       
    98     /**
       
    99      * Repeated calls to nextBoolean produce at least two distinct results
       
   100      */
       
   101     public void testNextBoolean() {
       
   102         boolean f = ThreadLocalRandom.current().nextBoolean();
       
   103         int i = 0;
       
   104         while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
       
   105             ++i;
       
   106         assertTrue(i < NCALLS);
       
   107     }
       
   108 
       
   109     /**
       
   110      * Repeated calls to nextFloat produce at least two distinct results
       
   111      */
       
   112     public void testNextFloat() {
       
   113         float f = ThreadLocalRandom.current().nextFloat();
       
   114         int i = 0;
       
   115         while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
       
   116             ++i;
       
   117         assertTrue(i < NCALLS);
       
   118     }
       
   119 
       
   120     /**
       
   121      * Repeated calls to nextDouble produce at least two distinct results
       
   122      */
       
   123     public void testNextDouble() {
       
   124         double f = ThreadLocalRandom.current().nextDouble();
       
   125         int i = 0;
       
   126         while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
       
   127             ++i;
       
   128         assertTrue(i < NCALLS);
       
   129     }
       
   130 
       
   131     /**
       
   132      * Repeated calls to nextGaussian produce at least two distinct results
       
   133      */
       
   134     public void testNextGaussian() {
       
   135         double f = ThreadLocalRandom.current().nextGaussian();
       
   136         int i = 0;
       
   137         while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
       
   138             ++i;
       
   139         assertTrue(i < NCALLS);
       
   140     }
       
   141 
       
   142     /**
       
   143      * nextInt(negative) throws IllegalArgumentException
       
   144      */
       
   145     @Test(expectedExceptions = IllegalArgumentException.class)
       
   146     public void testNextIntBoundedNeg() {
       
   147         int f = ThreadLocalRandom.current().nextInt(-17);
       
   148     }
       
   149 
       
   150     /**
       
   151      * nextInt(least >= bound) throws IllegalArgumentException
       
   152      */
       
   153     @Test(expectedExceptions = IllegalArgumentException.class)
       
   154     public void testNextIntBadBounds() {
       
   155         int f = ThreadLocalRandom.current().nextInt(17, 2);
       
   156     }
       
   157 
       
   158     /**
       
   159      * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
       
   160      * least two distinct results
       
   161      */
       
   162     public void testNextIntBounded() {
       
   163         // sample bound space across prime number increments
       
   164         for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
       
   165             int f = ThreadLocalRandom.current().nextInt(bound);
       
   166             assertTrue(0 <= f && f < bound);
       
   167             int i = 0;
       
   168             int j;
       
   169             while (i < NCALLS &&
       
   170                    (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
       
   171                 assertTrue(0 <= j && j < bound);
       
   172                 ++i;
       
   173             }
       
   174             assertTrue(i < NCALLS);
       
   175         }
       
   176     }
       
   177 
       
   178     /**
       
   179      * nextInt(least, bound) returns least <= value < bound; repeated calls
       
   180      * produce at least two distinct results
       
   181      */
       
   182     public void testNextIntBounded2() {
       
   183         for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
       
   184             for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
       
   185                 int f = ThreadLocalRandom.current().nextInt(least, bound);
       
   186                 assertTrue(least <= f && f < bound);
       
   187                 int i = 0;
       
   188                 int j;
       
   189                 while (i < NCALLS &&
       
   190                        (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
       
   191                     assertTrue(least <= j && j < bound);
       
   192                     ++i;
       
   193                 }
       
   194                 assertTrue(i < NCALLS);
       
   195             }
       
   196         }
       
   197     }
       
   198 
       
   199     /**
       
   200      * nextLong(negative) throws IllegalArgumentException
       
   201      */
       
   202     @Test(expectedExceptions = IllegalArgumentException.class)
       
   203     public void testNextLongBoundedNeg() {
       
   204         long f = ThreadLocalRandom.current().nextLong(-17);
       
   205     }
       
   206 
       
   207     /**
       
   208      * nextLong(least >= bound) throws IllegalArgumentException
       
   209      */
       
   210     @Test(expectedExceptions = IllegalArgumentException.class)
       
   211     public void testNextLongBadBounds() {
       
   212         long f = ThreadLocalRandom.current().nextLong(17, 2);
       
   213     }
       
   214 
       
   215     /**
       
   216      * nextLong(bound) returns 0 <= value < bound; repeated calls produce at
       
   217      * least two distinct results
       
   218      */
       
   219     public void testNextLongBounded() {
       
   220         for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
       
   221             long f = ThreadLocalRandom.current().nextLong(bound);
       
   222             assertTrue(0 <= f && f < bound);
       
   223             int i = 0;
       
   224             long j;
       
   225             while (i < NCALLS &&
       
   226                    (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
       
   227                 assertTrue(0 <= j && j < bound);
       
   228                 ++i;
       
   229             }
       
   230             assertTrue(i < NCALLS);
       
   231         }
       
   232     }
       
   233 
       
   234     /**
       
   235      * nextLong(least, bound) returns least <= value < bound; repeated calls
       
   236      * produce at least two distinct results
       
   237      */
       
   238     public void testNextLongBounded2() {
       
   239         for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
       
   240             for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
       
   241                 long f = ThreadLocalRandom.current().nextLong(least, bound);
       
   242                 assertTrue(least <= f && f < bound);
       
   243                 int i = 0;
       
   244                 long j;
       
   245                 while (i < NCALLS &&
       
   246                        (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
       
   247                     assertTrue(least <= j && j < bound);
       
   248                     ++i;
       
   249                 }
       
   250                 assertTrue(i < NCALLS);
       
   251             }
       
   252         }
       
   253     }
       
   254 
       
   255     /**
       
   256      * nextDouble(bound) throws IllegalArgumentException
       
   257      */
       
   258     public void testNextDoubleBadBound() {
       
   259         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   260         executeAndCatchIAE(() -> r.nextDouble(0.0));
       
   261         executeAndCatchIAE(() -> r.nextDouble(-0.0));
       
   262         executeAndCatchIAE(() -> r.nextDouble(+0.0));
       
   263         executeAndCatchIAE(() -> r.nextDouble(-1.0));
       
   264         executeAndCatchIAE(() -> r.nextDouble(Double.NaN));
       
   265         executeAndCatchIAE(() -> r.nextDouble(Double.NEGATIVE_INFINITY));
       
   266 
       
   267         // Returns Double.MAX_VALUE
       
   268 //        executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
       
   269     }
       
   270 
       
   271     /**
       
   272      * nextDouble(origin, bound) throws IllegalArgumentException
       
   273      */
       
   274     public void testNextDoubleBadOriginBound() {
       
   275         testDoubleBadOriginBound(ThreadLocalRandom.current()::nextDouble);
       
   276     }
       
   277 
       
   278     // An arbitrary finite double value
       
   279     static final double FINITE = Math.PI;
       
   280 
       
   281     void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
       
   282         executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
       
   283         executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
       
   284         executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
       
   285         executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
       
   286         executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
       
   287 
       
   288         // Returns NaN
       
   289 //        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
       
   290 //        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
       
   291 
       
   292         executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
       
   293 
       
   294         // Returns Double.MAX_VALUE
       
   295 //        executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
       
   296 
       
   297         executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
       
   298         executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
       
   299         executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
       
   300     }
       
   301 
       
   302     /**
       
   303      * nextDouble(least, bound) returns least <= value < bound; repeated calls
       
   304      * produce at least two distinct results
       
   305      */
       
   306     public void testNextDoubleBounded2() {
       
   307         for (double least = 0.0001; least < 1.0e20; least *= 8) {
       
   308             for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
       
   309                 double f = ThreadLocalRandom.current().nextDouble(least, bound);
       
   310                 assertTrue(least <= f && f < bound);
       
   311                 int i = 0;
       
   312                 double j;
       
   313                 while (i < NCALLS &&
       
   314                        (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
       
   315                     assertTrue(least <= j && j < bound);
       
   316                     ++i;
       
   317                 }
       
   318                 assertTrue(i < NCALLS);
       
   319             }
       
   320         }
       
   321     }
       
   322 
       
   323     /**
       
   324      * Invoking sized ints, long, doubles, with negative sizes throws
       
   325      * IllegalArgumentException
       
   326      */
       
   327     public void testBadStreamSize() {
       
   328         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   329         executeAndCatchIAE(() -> r.ints(-1L));
       
   330         executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
       
   331         executeAndCatchIAE(() -> r.longs(-1L));
       
   332         executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
       
   333         executeAndCatchIAE(() -> r.doubles(-1L));
       
   334         executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
       
   335     }
       
   336 
       
   337     /**
       
   338      * Invoking bounded ints, long, doubles, with illegal bounds throws
       
   339      * IllegalArgumentException
       
   340      */
       
   341     public void testBadStreamBounds() {
       
   342         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   343         executeAndCatchIAE(() -> r.ints(2, 1));
       
   344         executeAndCatchIAE(() -> r.ints(10, 42, 42));
       
   345         executeAndCatchIAE(() -> r.longs(-1L, -1L));
       
   346         executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
       
   347 
       
   348         testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
       
   349     }
       
   350 
       
   351     private void executeAndCatchIAE(Runnable r) {
       
   352         executeAndCatch(IllegalArgumentException.class, r);
       
   353     }
       
   354 
       
   355     private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
       
   356         Exception caught = null;
       
   357         try {
       
   358             r.run();
       
   359         }
       
   360         catch (Exception e) {
       
   361             caught = e;
       
   362         }
       
   363 
       
   364         assertNotNull(caught,
       
   365                       String.format("No Exception was thrown, expected an Exception of %s to be thrown",
       
   366                                     expected.getName()));
       
   367         Assert.assertTrue(expected.isInstance(caught),
       
   368                           String.format("Exception thrown %s not an instance of %s",
       
   369                                         caught.getClass().getName(), expected.getName()));
       
   370     }
       
   371 
       
   372     /**
       
   373      * A parallel sized stream of ints generates the given number of values
       
   374      */
       
   375     public void testIntsCount() {
       
   376         LongAdder counter = new LongAdder();
       
   377         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   378         long size = 0;
       
   379         for (int reps = 0; reps < REPS; ++reps) {
       
   380             counter.reset();
       
   381             r.ints(size).parallel().forEach(x -> {
       
   382                 counter.increment();
       
   383             });
       
   384             assertEquals(counter.sum(), size);
       
   385             size += 524959;
       
   386         }
       
   387     }
       
   388 
       
   389     /**
       
   390      * A parallel sized stream of longs generates the given number of values
       
   391      */
       
   392     public void testLongsCount() {
       
   393         LongAdder counter = new LongAdder();
       
   394         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   395         long size = 0;
       
   396         for (int reps = 0; reps < REPS; ++reps) {
       
   397             counter.reset();
       
   398             r.longs(size).parallel().forEach(x -> {
       
   399                 counter.increment();
       
   400             });
       
   401             assertEquals(counter.sum(), size);
       
   402             size += 524959;
       
   403         }
       
   404     }
       
   405 
       
   406     /**
       
   407      * A parallel sized stream of doubles generates the given number of values
       
   408      */
       
   409     public void testDoublesCount() {
       
   410         LongAdder counter = new LongAdder();
       
   411         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   412         long size = 0;
       
   413         for (int reps = 0; reps < REPS; ++reps) {
       
   414             counter.reset();
       
   415             r.doubles(size).parallel().forEach(x -> {
       
   416                 counter.increment();
       
   417             });
       
   418             assertEquals(counter.sum(), size);
       
   419             size += 524959;
       
   420         }
       
   421     }
       
   422 
       
   423     /**
       
   424      * Each of a parallel sized stream of bounded ints is within bounds
       
   425      */
       
   426     public void testBoundedInts() {
       
   427         AtomicInteger fails = new AtomicInteger(0);
       
   428         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   429         long size = 12345L;
       
   430         for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
       
   431             for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
       
   432                 final int lo = least, hi = bound;
       
   433                 r.ints(size, lo, hi).parallel().
       
   434                         forEach(x -> {
       
   435                             if (x < lo || x >= hi)
       
   436                                 fails.getAndIncrement();
       
   437                         });
       
   438             }
       
   439         }
       
   440         assertEquals(fails.get(), 0);
       
   441     }
       
   442 
       
   443     /**
       
   444      * Each of a parallel sized stream of bounded longs is within bounds
       
   445      */
       
   446     public void testBoundedLongs() {
       
   447         AtomicInteger fails = new AtomicInteger(0);
       
   448         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   449         long size = 123L;
       
   450         for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
       
   451             for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
       
   452                 final long lo = least, hi = bound;
       
   453                 r.longs(size, lo, hi).parallel().
       
   454                         forEach(x -> {
       
   455                             if (x < lo || x >= hi)
       
   456                                 fails.getAndIncrement();
       
   457                         });
       
   458             }
       
   459         }
       
   460         assertEquals(fails.get(), 0);
       
   461     }
       
   462 
       
   463     /**
       
   464      * Each of a parallel sized stream of bounded doubles is within bounds
       
   465      */
       
   466     public void testBoundedDoubles() {
       
   467         AtomicInteger fails = new AtomicInteger(0);
       
   468         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   469         long size = 456;
       
   470         for (double least = 0.00011; least < 1.0e20; least *= 9) {
       
   471             for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
       
   472                 final double lo = least, hi = bound;
       
   473                 r.doubles(size, lo, hi).parallel().
       
   474                         forEach(x -> {
       
   475                             if (x < lo || x >= hi)
       
   476                                 fails.getAndIncrement();
       
   477                         });
       
   478             }
       
   479         }
       
   480         assertEquals(fails.get(), 0);
       
   481     }
       
   482 
       
   483     /**
       
   484      * A parallel unsized stream of ints generates at least 100 values
       
   485      */
       
   486     public void testUnsizedIntsCount() {
       
   487         LongAdder counter = new LongAdder();
       
   488         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   489         long size = 100;
       
   490         r.ints().limit(size).parallel().forEach(x -> {
       
   491             counter.increment();
       
   492         });
       
   493         assertEquals(counter.sum(), size);
       
   494     }
       
   495 
       
   496     /**
       
   497      * A parallel unsized stream of longs generates at least 100 values
       
   498      */
       
   499     public void testUnsizedLongsCount() {
       
   500         LongAdder counter = new LongAdder();
       
   501         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   502         long size = 100;
       
   503         r.longs().limit(size).parallel().forEach(x -> {
       
   504             counter.increment();
       
   505         });
       
   506         assertEquals(counter.sum(), size);
       
   507     }
       
   508 
       
   509     /**
       
   510      * A parallel unsized stream of doubles generates at least 100 values
       
   511      */
       
   512     public void testUnsizedDoublesCount() {
       
   513         LongAdder counter = new LongAdder();
       
   514         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   515         long size = 100;
       
   516         r.doubles().limit(size).parallel().forEach(x -> {
       
   517             counter.increment();
       
   518         });
       
   519         assertEquals(counter.sum(), size);
       
   520     }
       
   521 
       
   522     /**
       
   523      * A sequential unsized stream of ints generates at least 100 values
       
   524      */
       
   525     public void testUnsizedIntsCountSeq() {
       
   526         LongAdder counter = new LongAdder();
       
   527         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   528         long size = 100;
       
   529         r.ints().limit(size).forEach(x -> {
       
   530             counter.increment();
       
   531         });
       
   532         assertEquals(counter.sum(), size);
       
   533     }
       
   534 
       
   535     /**
       
   536      * A sequential unsized stream of longs generates at least 100 values
       
   537      */
       
   538     public void testUnsizedLongsCountSeq() {
       
   539         LongAdder counter = new LongAdder();
       
   540         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   541         long size = 100;
       
   542         r.longs().limit(size).forEach(x -> {
       
   543             counter.increment();
       
   544         });
       
   545         assertEquals(counter.sum(), size);
       
   546     }
       
   547 
       
   548     /**
       
   549      * A sequential unsized stream of doubles generates at least 100 values
       
   550      */
       
   551     public void testUnsizedDoublesCountSeq() {
       
   552         LongAdder counter = new LongAdder();
       
   553         ThreadLocalRandom r = ThreadLocalRandom.current();
       
   554         long size = 100;
       
   555         r.doubles().limit(size).forEach(x -> {
       
   556             counter.increment();
       
   557         });
       
   558         assertEquals(counter.sum(), size);
       
   559     }
       
   560 
       
   561 }