java中ThreadLocalRandom的使用詳解
在java中我們通常會需要使用到java.util.Random來便利的生產(chǎn)隨機數(shù)。但是Random是線程安全的,如果要在線程環(huán)境中的話就有可能產(chǎn)生性能瓶頸。
我們以Random中常用的nextInt方法為例來具體看一下:
public int nextInt() {
return next(32);
}
nextInt方法實際上調(diào)用了下面的方法:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
從代碼中我們可以看到,方法內(nèi)部使用了AtomicLong,并調(diào)用了它的compareAndSet方法來保證線程安全性。所以這個是一個線程安全的方法。
其實在多個線程環(huán)境中,Random根本就需要共享實例,那么該怎么處理呢?
在JDK 7 中引入了一個ThreadLocalRandom的類。ThreadLocal大家都知道就是線程的本地變量,而ThreadLocalRandom就是線程本地的Random。
我們看下怎么調(diào)用:
ThreadLocalRandom.current().nextInt();
我們來為這兩個類分別寫一個benchMark測試:
public class RandomUsage {
public void testRandom() throws InterruptedException {
ExecutorService executorService=Executors.newFixedThreadPool(2);
Random random = new Random();
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
callables.add(() -> {
return random.nextInt();
});
}
executorService.invokeAll(callables);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(RandomUsage.class.getSimpleName())
// 預熱5輪
.warmupIterations(5)
// 度量10輪
.measurementIterations(10)
.forks(1)
.build();
new Runner(opt).run();
}
}
public class ThreadLocalRandomUsage {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void testThreadLocalRandom() throws InterruptedException {
ExecutorService executorService=Executors.newFixedThreadPool(2);
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
callables.add(() -> {
return ThreadLocalRandom.current().nextInt();
});
}
executorService.invokeAll(callables);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(ThreadLocalRandomUsage.class.getSimpleName())
// 預熱5輪
.warmupIterations(5)
// 度量10輪
.measurementIterations(10)
.forks(1)
.build();
new Runner(opt).run();
}
}
分析運行結果,我們可以看出ThreadLocalRandom在多線程環(huán)境中會比Random要快。
本文的例子可以參考https://github.com/ddean2009/learn-java-concurrency/tree/master/ThreadLocalRandom
到此這篇關于java中ThreadLocalRandom的使用詳解的文章就介紹到這了,更多相關java ThreadLocalRandom內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring MVC Mybatis多數(shù)據(jù)源的使用實例解析
項目需要從其他網(wǎng)站獲取數(shù)據(jù),因為是臨時加的需求,這篇文章主要介紹了Spring MVC Mybatis多數(shù)據(jù)源的使用實例解析,需要的朋友可以參考下2016-12-12
Android開發(fā)Kotlin實現(xiàn)圓弧計步器示例詳解
這篇文章主要為大家介紹了Android開發(fā)Kotlin繪制圓弧計步器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
java組件smartupload實現(xiàn)上傳文件功能
這篇文章主要為大家詳細介紹了java組件smartupload實現(xiàn)上傳文件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10
java?mybatis如何操作postgresql?array數(shù)組類型
這篇文章主要介紹了java?mybatis如何操作postgresql?array數(shù)組類型,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01

