Java中多线程环境使用Random
Contents
Random
根据 JDK 文档介绍, 它是线程安全的.
Instances of {@code java.util.Random} are threadsafe.
但文档中说, 在跨线程使用 Random
时, 它的性能比较低下.
ThreadLocalRandom
这个是在 JDK >= 1.7
时出现的, 当在多线程环境中使用 Random
时, 请考虑使用 ThreadLocalRandom
. 因为它在多线程中相比 Random
性能更高. 一般的使用方式:
ThreadLocalRandom.current().nextX(...)
性能基准对比
@Benchmark
public void testRandom(){
GenerateIdUtils.generateBidId();
}
@Benchmark
public void testThreadLocalRandom(){
GenerateIdUtils.generateUnfrozenBidIdThreadLocal();
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(BenchmarkTest.class.getSimpleName())
.forks(1)
.warmupIterations(5)
.measurementIterations(5)
.build();
new Runner(opt).run();
}
public static String generateBidId() {
final String randomStr = getStringRandom(8);
return BID_PREFIX + randomStr;
}
public static String generateUnfrozenBidId() {
final String randomStr = getStringRandom(8);
return BID_UNFROZEN_PREFIX + randomStr;
}
public static String generateUnfrozenBidIdThreadLocal() {
final String randomStr = getStringRandomThraedLocal(8);
return BID_UNFROZEN_PREFIX + randomStr;
}
// 生成随机数字和字母,
private static String getStringRandomThraedLocal(final int length) {
final StringBuilder buf = new StringBuilder();
// 参数length,表示生成几位随机数
final ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
for (int i = 0; i < length; i++) {
// 输出字母还是数字
if (threadLocalRandom.nextInt(2) % 2 == 0) {
buf.append((char) (threadLocalRandom.nextInt(26) + 97));
} else {
buf.append(threadLocalRandom.nextInt(10));
}
}
return buf.toString();
}
private static final Random random = new Random();
// 生成随机数字和字母,
private static String getStringRandom(final int length) {
final StringBuilder buf = new StringBuilder();
// 参数length,表示生成几位随机数
for (int i = 0; i < length; i++) {
// 输出字母还是数字
if (random.nextInt(2) % 2 == 0) {
buf.append((char) (random.nextInt(26) + 97));
} else {
buf.append(random.nextInt(10));
}
}
return buf.toString();
}
基准压测结果:
Benchmark Mode Cnt Score Error Units
BenchmarkTest.testRandom thrpt 5 3586.838 ± 985.575 ops/ms
BenchmarkTest.testThreadLocalRandom thrpt 5 5676.495 ± 2348.271 ops/ms