出于某种原因,我常想,java.util.Random是线程安全的,一拉HashMap或BitSet,并且Math.random()被实现为包装访问Random与synchronized块,或ThreadLocalRandom.current().nextDouble().
实际上事实证明它java.util.Random是线程安全的(通过原子).因此需要注意的是:即使我需要在单个线程中使用一些随机输入,使用ThreadLocalRandom也是有意义的,因为内部没有原子读写,编译为锁定指令并发出内存屏障.
而且,由于Java 8 ThreadLocalRandom本质上是一个单例,它的状态保存在某些java.lang.Thread类的字段中.因此,方法ThreadLocalRandom.current()不是访问ThreadLocalMap,而只是静态字段读取,即非常便宜.
我有两个问题:
从计算机科学的角度来看,几个线性同余随机生成器(以ThreadLocalRandoms 的方式初始化)的输出是否与单个线性同余随机生成器(java.util.Random实例)的输出相同"随机" ?
如果回答的第一个问题是肯定的,是否有任何理由写的建设new Random()(不含种子)来代替ThreadLocalRandom.current(),永远不会消失?
更新.我应该调用像ThreadLocalRandom.current().ints().parallel().collect(...)可能是不正确的,因为线程的随机数生成器的状态可能中未初始化ForkJoinPool的工作线程,但看起来,ThreadLocalRandom覆盖方法ints(),longs()以及doubles(),使得上述结构正确.
java.util.Random的实例是线程安全的.但是,跨线程并发使用相同的java.util.Random实例可能会遇到争用并因此导致性能不佳.请考虑在多线程设计中使用ThreadLocalRandom.
表现不佳背后的原因可能是什么?
我在一个高并发应用程序上工作.在应用程序代码中,我尝试尽可能避免同步.最近,在比较非同步和同步代码版本的测试性能时,结果表明同步代码的执行速度比非同步代码快三到四倍.
经过一些实验,我来到了这个测试代码:
private static final Random RND = new Random();
private static final int NUM_OF_THREADS = 3;
private static final int NUM_OF_ITR = 3;
private static final int MONKEY_WORKLOAD = 50000;
static final AtomicInteger lock = new AtomicInteger();
private static void syncLockTest(boolean sync) {
System.out.println("syncLockTest, sync=" + sync);
final AtomicLong jobsDone = new AtomicLong();
final AtomicBoolean stop = new AtomicBoolean();
for (int i = 0; i < NUM_OF_THREADS; i++) {
Runnable runner;
if (sync) {
runner = new Runnable() { …Run Code Online (Sandbox Code Playgroud) 我可以scala.util.Random在多个线程中使用同一个对象吗?
提前感谢花时间看我的问题.任何有同样问题的人都希望我们能得到解决方案......
所以基本上我有一个应用程序同时旋转2个硬币并显示结果.
这种方法产生第一枚硬币......
public void coinResult1(){
ImageView coin1View = (ImageView) findViewById(R.id.coin1);
Random r = new Random();
int coin1result = r.nextInt(2);
if (coin1result == 0){
coin1View.setBackgroundResource(R.drawable.coinheads);
coinresult1 = 0;
}
else if (coin1result == 1) {
coin1View.setBackgroundResource(R.drawable.cointails);
coinresult1 = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
这是第二枚硬币
public void coinResult2(){
ImageView coin2View = (ImageView) findViewById(R.id.coin2);
Random r = new Random();
int coin2result = r.nextInt(2);
if (coin2result == 0){
coin2View.setBackgroundResource(R.drawable.coinheads);
coinresult2 = 0;
}
else if (coin2result == 1) {
coin2View.setBackgroundResource(R.drawable.cointails);
coinresult2 = 1;
}
} …Run Code Online (Sandbox Code Playgroud) 这个问题中的 while 循环是线程安全的:AtomicInteger thread safety。如果我在线程安全的 while 循环中插入 randomSum 方法,代码是否仍然是线程安全的?还是应该同步 randomSum 方法?
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class Print implements Runnable {
static AtomicInteger atomicInteger = new AtomicInteger(0);
static Random random = new Random(1);
public static int randomSum() {
int sum = 0;
for (int i = 0; i < 10; i++) {
sum += random.nextInt();
}
return sum;
}
@Override
public void run() {
while (atomicInteger.getAndIncrement() < 100)
System.out.println(randomSum() + " " + Thread.currentThread());
}
public …Run Code Online (Sandbox Code Playgroud) java ×5
random ×3
concurrency ×2
android ×1
contention ×1
java-8 ×1
performance ×1
probability ×1
scala ×1