Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does ThreadLocalRandom proper to use in VirtualThread in Java Loom

In video [1:23] Jose Paumard talks about why using ThreadLocal is evil; especially, if the code creates countless (virtual) threads.

  • Can we say the same thing for ThreadLocalRandom?
  • Should people use Random over ThreadLocalRandom in (virtual) threads?
  • Or is it just name similarity that we should stick with ThreadLocalRandom?


    Additional notes...
    According to simple tests, Both Random and ThreadLocalRandom works:
public static void threadLocalRandomTest() {
        enum TestType {
            useNewThreadLocalRandom, useNewRandom,
            ReUseThreadLocal, ReUseRandom,
            ReUseGlobalRandom,
            customThreadLocalRandom, customRandom
        }
        var testType = TestType.useNewThreadLocalRandom;
        var rg = new Random();
        IntStream.range(0, 1_000_000).forEach(i -> {
            if (testType == TestType.useNewThreadLocalRandom) {//63mb->60mb
                IntStream.range(0, 100).forEach(j -> {
                    ThreadLocalRandom.current().nextFloat(1);
                });
            }
            if (testType == TestType.useNewRandom) {//326mb->323mb
                IntStream.range(0, 100).forEach(j -> {
                    new Random().nextFloat(1);
                });
            }
            if (testType == TestType.ReUseThreadLocal) {//65mb->61mb
                var r = ThreadLocalRandom.current();
                IntStream.range(0, 100).forEach(j -> {
                    r.nextFloat(1);
                });
            }
            if (testType == TestType.ReUseRandom) {//111mb->108mb
                var r = new Random();
                IntStream.range(0, 100).forEach(j -> {
                    r.nextFloat(1);
                });
            }
            if (testType == TestType.ReUseGlobalRandom) {//64mb->61mb
                IntStream.range(0, 100).forEach(j -> {
                    rg.nextFloat(1);
                });
            }
        });
    }
like image 643
Tugalsan Karabacak Avatar asked Jul 03 '26 18:07

Tugalsan Karabacak


1 Answers

Jose Paumard's warning about ThreadLocal being "evil" with virtual threads refers to arbitrary ThreadLocal usage, which would cause memory bloat with millions of virtual threads. But ThreadLocalRandom is safe. Each virtual thread gets one tiny ThreadLocalRandom instance (just 16 bytes of state), and it avoids contention (unlike shared Random), and has lower overhead than creating new Random instances repeatedly (as your tests show: 60MB vs 323MB).

Using new Random() in tight loops (like your useNewRandom test) creates massive GC pressure. Even ReUseRandom (108MB) underperforms vs ThreadLocalRandom (60MB) because it serializes access via synchronization.

Keep using ThreadLocalRandom.current(). It's the correct choice for virtual threads. Your tests accidentally prove this: the lowest memory usage comes from reusing ThreadLocalRandom (60MB), while new Random() is 5x worse.

void generateRandoms() {
    // Reuse the thread-local instance (no per-call overhead)
    var random = ThreadLocalRandom.current();
    IntStream.range(0, 100).forEach(j -> 
        random.nextFloat()
    );
}
like image 155
eyesoflight Avatar answered Jul 06 '26 09:07

eyesoflight



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!