Thread Safety of SecureRandom
Before Java 9 the thread safety contract of SecureRandom and SecureRandomSPI was not specified (see JDK-7004967). As of Java 8 the situation was that SecureRandom was thread safe by virtue of being synchronized internally. This of course limits parallelism.
With Java 9 the situation has now changed (see JDK-8169871 and JDK-8165115). A SecureRandomSpi can now optionally document that it is thread safe. If it is marked as thread safe then SecureRandom will not synchronize access to it. If the SecureRandomSPI is not marked as thread safe then the behavior is the same as in Java 8 and SecureRandom will synchronize all access to it.
All thread safe SecureRandomSPIs can be found with
Arrays.stream(Security.getProviders())
.flatMap(p -> p.entrySet().stream())
.filter(e -> ((String) e.getKey()).startsWith("SecureRandom."))
.filter(e -> ((String) e.getKey()).endsWith(" ThreadSafe"))
.filter(e -> e.getValue().equals("true"))
.map(e -> (String) e.getKey())
.map(e -> e.substring("SecureRandom.".length(), e.length() - " ThreadSafe".length()))
.sorted()
.forEach(System.out::println);
With Oracle JDK 9.0.1 on macOS this prints
DRBG
NativePRNG
NativePRNGBlocking
NativePRNGNonBlocking
SHA1PRNG
Note that even though a SecureRandomSPI may be marked as thread safe the implementation may still acquire a lock like the NativePRNG variants.